#include "component.h"
#include "local_main.h"
#include "time.h"
//#include "func_led.h"
//#include "func_audio.h"
#include "application.h"
#include "nb_comp.h"

#define ATE_MAIN_LOG(format, ...) __OSAL_LOG("[ate.c:%d] " format "\r\n", __LINE__, ##__VA_ARGS__)
#define __ATE_MAIN_LOG(format, ...) __OSAL_LOG(format, ##__VA_ARGS__)

// 老化时: 不同电机转速不一样, 设置不同定时器时间, 让电机转动到位. 单位ms
#ifndef ATE_AGING_TIMER
    #define ATE_AGING_TIMER 20
#endif

#define TIME_DEC2BCD(t) OSAL_DEC2BCD(t[0]), \
                        OSAL_DEC2BCD(t[1]), \
                        OSAL_DEC2BCD(t[2]), \
                        OSAL_DEC2BCD(t[3]), \
                        OSAL_DEC2BCD(t[4]), \
                        OSAL_DEC2BCD(t[5])

/* 产测模式接收消息命令 */
#define CMD_CHANGE_WORK_MODE 0x01        //门锁产测模式切换
#define CMD_SET_DOORLOCK_PARA 0x05       //设置门锁参数
#define CMD_BLE_CAL 0x06                 //蓝牙频偏校准
#define CMD_FVN_TEST 0x09                //指静脉测试
#define CMD_READ_LOCK_VOLTAGE 0x10       //读取门锁电压
#define CMD_TOUCH_TEST 0x11              //按键测试
#define CMD_FPT_TEST 0x12                //指纹测试
#define CMD_CARD_TEST 0x13               //卡片测试
#define CMD_LOCKBODY_TEST 0x14           //锁体测试
#define CMD_READ_VERSION 0x15            //版本号查询
#define CMD_READ_WRITE_SECURITYCODE 0x16 //防伪码查询/写入
#define CMD_COREBOARD_TEST 0x17          //核心板测试--暂时没用到
#define CMD_READ_LOCK_TIME 0x18          //读取门锁时间
#define CMD_BLUETOOTH_TEST 0x19          //蓝牙测试
#define CMD_LOCK_SLEEP 0x1A              //门锁休眠
#define CMD_SEND_FPT_LIC 0x1B            //下发指纹许可文件
#define CMD_UPDATE_FIREWARE 0x1C         //升级门锁固件
#define CMD_KEYBOARD_LIGHT_TEST 0x1D     //指示灯测试
#define CMD_PLAY_AUDIO 0x1E              //播放语音
#define CMD_WRITE_BLE_KEY 0x1F           //写BLE-KEY
#define CMD_WRITE_BLE_SN 0x0F            //写BLE-SN
#define CMD_LED_CTRL 0x30                //led灯控制
#define CMD_KILL_DOG 0x32                //杀狗命令
#define CMD_OLED_TEST 0x33               //OLED测试
#define CMD_RECOVERY 0x34                //门锁恢复出厂设置
#define CMD_ENABLE_SWD 0x38              //使能SWD接口
#define CMD_WIFI_POWER_CTRL_TEST 0x39    //wifi电源控制脚测试
#define CMD_TOF_TEST 0x3B                //TOF传感器测试
#define CMD_FACE_TEST 0x3C               //人脸测试
#define CMD_GSENSOR_TEST 0x3E            //加速度传感器测试
#define CMD_SET_FACE_ENC_KEY_TEST 0x3F   //人脸设定量产加密的秘钥
#define CMD_PSENSOR_TEST 0X41        //惯性传感器测试
#define CMD_TEST_READ_MODE_VERSION 0x47  //读取模组版本
#define CMD_TOF_CAL 0x48                 //TOF传感器校准
#define CMD_EXTERN_MOTO 0x4C             //外置电机测试
#define CMD_MSENSOR_TEST 0x4B            //门磁传感器测试
#define CMD_TEST_INT_IO 0x4A             //测试视频模块的中断脚（讯美）
// #define CMD_READ_REARBOARDVERSION 0x4D   //副板固件版本查询--不用
#define CMD_READ_KDSWIFI_VERSION 0x4E    //读取凯迪仕wifi模块版本号
#define CMD_HIGH_SPEED_HALL_TEST 0X4F    //高速霍尔测试
#define CMD_WIFI_BLE_MAC 0x51            //WIFI BLE测试
#define CMD_XM_WIFI_RSSI_TEST 0X53       //讯美搜索热点信号测试
#define CMD_XM_MIC_TEST 0X54             //讯美mic测试
#define CMD_XM_VOICE_TEST 0X55           //讯美语音测试
#define CMD_XM_VIDEO_TEST 0X56           //讯美视频测试
#define CMD_XM_PIR_TEST 0X57             //讯美PIR测试
#define CMD_XM_IN_OUT_TEST_MODE 0X58     //讯美模组进入退出产测模式
#define CMD_OTA_LINK_TEST 0X59           //讯美OTA链路测试 讯美 人脸之间升级  讯美锁端升级等
#define CMD_XM_RED_LED_TEST 0X5A         //讯美红外补光灯测试
#define CMD_START_OTA 0x5C               //启动OTA
#define CMD_SET_SERVER_PARA 0x5D         //配置服务器参数
#define CMD_SET_LOGO 0x5E                //配置开机logo
#define CMD_LOCK_DAI_TEST 0X5F 		     //外贸锁体测试
#define CMD_READ_LOGO 0x60               //读取开机logo
#define CMD_READ_SERVER_PARA 0x61        //读取服务器参数
// #define CMD_READ_HANDLE_VERSION 0x63     //读取感应把手版本号--不用
#define CMD_READ_ERROR_CODE 0x6C         //读取故障码
#define CMD_XM_SET_LANGUAGE 0x6D         // 设置讯美模块的语言
#define CMD_READ_ANY_RECORDS 0x70        //读取记录
#define CMD_XM_READ_WIFI_MAC 0x80        //读取讯美WiFi MAC地址
#define CMD_MANUAL_LOCK_DAI_TEST 0x81    //呆锁手动锁体测试
#define CMD_STUDY_NEXT_TIME_FLAG 0x82    //自学习标志
#define CMD_READ_ALL_VERSION 0x85        //读取所有门锁版本和型号信息
#define CMD_BLE_FRE_TEST 0x87            //蓝牙RF定频测试
#define CMD_EEPROM_RESTORE 0x88          //清空eeprom
#define CMD_WR_SERVICE_INFO 0x8B         //读写服务配置信息
#define CMD_XUNMEI_DEV_TEST 0X8D         //讯美外设测试

#define CMD_NB_CSQ          0XA1   //读取CSQ

/* 产测模式上报消息命令 */
#define CMD_LOCK_STATUS_REPORT 0x20      //门锁休眠/上电/唤醒状态上报
#define CMD_READ_KEY_REPORT 0x21         //门锁上报按下键值
#define CMD_READ_FPT_REPORT 0x22         //门锁上报指纹获取到图像
#define CMD_READ_CARD_REPORT 0x23        //门锁上报读取到卡
#define CMD_PSENSOR_REPORT 0X25      //惯性传感器上报
#define CMD_TOF_CAL_RESULT_REPORT 0x26   //上报TOF校准结果
#define CMD_READ_FVN_REPORT 0x28         //门锁上报指静脉获取到图像
#define CMD_WRITE_FPT_LIC_END 0x2B       //门锁上报指纹烧录许可文件结束
#define CMD_READ_DISTANCE_REPORT 0x2D    //门锁上报距离传感器值
#define CMD_READ_FACE_REPORT 0x2E        //门锁上报人脸识别结果
#define CMD_SET_FACE_ENC_KEY_REPORT 0x2F //上报人脸设定量产加密的秘钥结果
#define CMD_XM_PERIPHERAL_REPORT 0X30    //讯美外设测试主动上报
#define CMD_TEST_USB_REPORT 0X90         //产测usb链路通信结果上报
#define CMD_EXTEND_NETWORK_SET 0X91      //控制锁端与模块配网连接
/*ACK回复的错误类型*/
#define CMD_EXECUTING 0x00  //命令正在执行，还需再次执行才能得到结果
#define CMD_EXE_ONCE 0x01   //命令执行完一次，还需要再次执行
#define CMD_EXE_OK 0x80     //命令执行成功
#define CMD_EXE_ERR 0x81    //命令执行失败
#define CMD_EXE_OK_END 0x82 //命令执行结束（当有多个应答包时，最后一个应答发0x82）

//讯美模组相关测试
#define TX_CMD_READ_XUNMEI_SN 0X09       //读取讯美模块的SN
#define TX_CMD_LOWPOWER_MODE 0X10        //使模块进入低功耗模式
#define CMD_XM_BUTTON_REPORT 0X17        //讯美按键上报
#define TX_CMD_XM_WIFI_SCAN_REPORT 0X18  //Wifi 扫描结果上报
#define TX_CMD_XM_USB_TEST_REPORT 0X19   //usb测试结果上报
#define TX_CMD_XM_VEDIO_TEST_REPORT 0X1A //讯美摄像头结果上报
#define TX_CMD_XM_PIR_TEST_REPORT 0X1B   //讯美pir测试结果上报
#define TX_CMD_XM_ALL_DEV_REPORT 0X22    //讯美所有测试结果上报
#define TX_CMD_LANG_SET 0X30             //设置语言
#define TX_CMD_DEFAULT_SET 0X31          //恢复出厂设置
#define TX_CMD_XM_VERSION 0X34           //获取讯美所有MCU版本信息
#define TX_CMD_XM_LCD_TEST 0X35          //讯美显示屏测试
#define TX_CMD_XM_BUTTON_TEST 0X36       //讯美按键测试
#define TX_CMD_XM_WIFI_TEST 0X37         //讯美WIFI测试
#define TX_CMD_XM_FACE_USB_TEST 0X38     //讯美人脸USB测试
#define TX_CMD_XM_MODULE_TEST 0X39       //讯美模组外设测试
#define TX_CMD_XM_TEST_MODE 0X3B         //讯美进入退出产测模式
#define TX_CMD_XM_SET_SERVER_PARA 0x3C   //配置服务器参数
#define TX_CMD_XM_SET_LOGO 0x3D          //配置开机logo
#define TX_CMD_XM_READ_SERVER_PARA 0x3F  //读取服务器参数
#define TX_CMD_XM_READ_LOGO 0x40         //读取开机logo
#define TX_CMD_XM_READ_MAC 0X45          //读取WIFI MAC地址
#define TX_CMD_CLEAR_WIFI_INFO 0x46      //清除模组wifi信息
#define TX_CMD_XM_SET_BOOT_ADDR 0x55     //配置根证书地址
#define TX_CMD_XM_READ_BOOT_ADDR 0x56     //读取根证书地址

#define KEY_TEST 0x01
#define FPT_TEST 0x02
#define CARD_TEST 0x03
#define UNLOCK_TEST 0x04
#define LOCKED_TEST 0x05
#define LED_TEST 0x06
#define DISTANCE_TEST 0x07
#define FACE_TEST 0x08
#define DOOR_SENSOR_TEST 0x09
#define XM_IO_TEST 0x0A
#define FVN_TEST 0x0B
#define PVN_TEST 0x0C

#define ESN_LENG 0x0D
#define LOCK_STOP_TEST 0x0E
/* 视频测试扫描的二维码内容 */
#define VIDEO_TEST_QRCODE_STRING    "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdedghijklmnopqrstuvwxyz0987654321"

static uint8_t test_type = 0xff; //测试类型
static uint8_t newFaceReportFlag =0;//新的人脸上报标志
static uint8_t newBatTestFlag =0;//新的电池电量测试标志
uint8_t xunmei_peripherals_cmd = 0; //讯美外设测试指令 用于回ACK包
uint8_t xunmei_peripherals_type =0xff; //讯美外设类型
static uint8_t handle_version[10] = {0};

AppHandle_t app_handle = NULL;
static uint8_t lcd_test_flag =0;//显示屏测试
/* 产测模式 */
static TestMode_enum_t productionTestMode = TESTMODE_UNKNOW;
/* 蓝牙MAC的存储地址 */
static uint8_t bleMacSaveAddr[7] = {0};
static uint8_t bleKey[13] = {0}; // 产测写入的key
static uint8_t bleESN[14] = {0}; // 产测写入的ESN

static uint8_t xmVersions[96] = {0}; // 存放讯美版本号

static char wifi_ssid[32] = {0}; //测试的wifi rssi

static uint8_t Lock_dai_test = 0; //呆锁测试类型  0：自动检测 1：手动检测

static uint8_t xm_language = 0;   // 产测写入的语言序号

__EFRAM uint32_t err_code = 0; //故障码
uint8_t sleep_flag = 0;

static DFU_DevNum_enum_t DFU_devnum = DFU_DEVNUM_MAX;/* 当前版本查询的设备 */
static char video_ver[32] = {0};
static char uvc_ver[32] = {0};

static void extend_kds_send_callback(uint8_t cmd, void *data, uint16_t len);
static void ATE_test_process_cb(TimerHandle_stu_t handle);
static void ATE_TouchMsgCb(void *msg, uint16_t len);
static void ATE_IrSensorCb(void *msg, uint16_t len);
static void ATE_ButtonMsgCb(void *msg, uint16_t len);
static void ATE_FingerMsgCb(void *msg, uint16_t len);
static void ATE_CardMsgCb(void *msg, uint16_t len);
static void ATE_FaceMsgCb(void *msg, uint16_t len);
static void ATE_DSensorMsgCb(void *msg, uint16_t len);
static void ATE_LockPsensorMsgCb(void *msg, uint16_t len);
static void ATE_LockMsgCb(void *msg, uint16_t len);
static void ATE_RemoteXm_SetLowPower(void);
static void ATE_RemoteXm_Send(uint8_t cmd, uint8_t *pdata, uint16_t len, cmd_packet_type pack_type);
static void ATE_XunmeiMsgCb(void *msg, uint16_t len);
static void ATE_WifiMsgCb(void *msg, uint16_t len);
#ifdef CAMERA_SUB_DEVICE
static void ATE_CameraCb(void *msg, uint16_t len);
static void ATE_PirCb(void *msg, uint16_t len);
#endif
static void ATE_FingerveinMsgCb(void *msg, uint16_t len);
static void ATE_PvnMsgCb(void *msg, uint16_t len);
static void ATE_FacePvnReport(uint8_t cmd ,uint8_t type ,uint8_t statu);

typedef enum
{
    LED_TEST_ALL,         //测试所有LED灯（有感应把手时，主控控制开关门指示灯）
    LED_TEST_OPEN_CLOSE,  //通过感应把手控制开关门指示灯
    LED_TEST_WAIT_FINISH, //已经转发数据给感应把手，等待感应把手完成测试
} LedTestStatus_enum_t;
static LedTestStatus_enum_t led_test_status;

#pragma pack(1)
#ifdef BAT_ENCRY
typedef struct
{
    Bat_Encrypt_Msg_t   encBatInfo;
    Bat_Encrypt_PAGE2_t BatPage2;
    Bat_Encrypt_PAGE3_t BatPage3;
    Bat_Encrypt_PAGE4_t BatPage4;
} ATE_Bat_Encrypt_t;
ATE_Bat_Encrypt_t AteBatInfo;//加密电池信息
#endif
typedef struct
{
    uint32_t updateFlag; //4
    uint8_t devNum[4];   //4
    uint8_t reserve[24]; //24
} gram_stu_t;

typedef struct
{
    uint8_t type;      //记录类型
    uint16_t number;   //记录个数
    uint16_t sn;       //包序号
    uint8_t record[9]; //记录数据
} Ack_Records_stu_t;
#pragma pack() //32byte

#if defined(KAADAS_NO_MENU)
/**
  * @brief  复位NV里面所有数据
  *
  * @note   恢复出厂设置时调用
  */
static void ATE_NvReset(void)
{
    NvSystemParam_stu_t sys_data;

    OSAL_NvRead(0, &sys_data, sizeof(NvSystemParam_stu_t));
    /* 用户参数恢复默认，产测参数保持 */
    sys_data.sys_flag = 0;                                 // 状态标志（bit0:防撬报警 bit1:布防报警 bit2:布防状态 bit3:反锁状态…… ）
    sys_data.auto_lock_time = DEFAULT_AUTO_LOCK_TIME;      // 自动上锁时间(s)
    sys_data.amMode = DEFAULT_OPEN_LOCK_MODE;              // 自动模式/手动模式（自动上锁/关闭自动上锁）
    sys_data.powerSavingMode = POWER_SAVING_CLOSE;         // 节能模式
    sys_data.videoIsOpen = DEFAULT_VIDEO_FUNC;             // 视频功能是否开启 默认关闭
    sys_data.faceIsOpen = DEFAULT_FACE_FUNC;               // 人脸功能是否开启 默认关闭
    sys_data.en_handle = DEFAULT_TOUCH_HANDLE_FUNC;        // 感应把手使能
    sys_data.hoverAlarmIsEable = DEFAULT_HOVER_ALARM_FUNC; // 徘徊报警使能
    sys_data.hoverAlarmLevel = DEFAULT_HOVER_ALARM_LEVEL;  // 徘徊报警等级
    sys_data.default_language = DEFAULT_LANGUAGE;          // 默认语言
    sys_data.touchKeyLockCnt = 0;                          // 独立上锁键按下次数 //触摸上锁键按下计数值
    sys_data.verifyErrCount = 0;                           // 验证失败的次数
    sys_data.verifyErrTime = 0;                            // 验证失败的时间
    sys_data.systemLockedTime = 0;                         // 系统锁定的时间
    sys_data.openLockTimes = 0;                            // 开锁次数
    sys_data.bindFlag = 0;                                 // ble绑定标志
    memset(sys_data.PWDb, 0, 16);                          // pwdb清零
#if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
    memset((uint8_t *)&sys_data.ota_info, 0, sizeof(OTAInfo_stu_t)); //清空ota信息
#endif
    OSAL_NvWrite(0, &sys_data, sizeof(NvSystemParam_stu_t));

    SYS_CALL(Record_Delete);                  // 删除所有记录
    SYS_CALL(Users_SetSafeMode, RESET);       // 删除所有用户
    SYS_CALL(Users_Del, 0XFF, 0XFF, NULL, 0); // 删除所有用户
    SYS_CALL(Face_Delete_Start, 0, 0xFF);     // 删除全部人脸
    SYS_CALL(Face_Factory);                   // 删除所有人脸模板
    Finger_DeleteImage(0, 100);               // 删除所有指纹模板

    SYS_CALL(dsensor_set_sensitivity, DSENSOR_SENS_H); // 设置默认的传感器灵敏度

    Audio_SetMuteMode(RESET);                     // 语音模式
    Audio_SetVolume(100);                         // 音量设置成100
    Audio_SetLanguage(DEFAULT_LANGUAGE);          // 设置默认语言

#if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
    Wifi_Disconnect(0);
#else
    ATE_RemoteXm_Send(TX_CMD_LANG_SET, &sys_data.default_language, 1, COMMAND);
    ATE_RemoteXm_Send(TX_CMD_DEFAULT_SET, NULL, 0, COMMAND);
    ATE_RemoteXm_Send(TX_CMD_CLEAR_WIFI_INFO, NULL, 0, COMMAND);
#endif

    Audio_Play(YI_HUI_FU_DAO_CHU_CHANG_SHE_ZHI, RESET);
    OSAL_SystemReset(4000);
}
#else
/**
  * @brief  复位NV里面所有数据
  *
  * @note   恢复出厂设置时调用
  */

static void ATE_NvReset(void)
{
    Local_NvReset(1);
}
#endif

/**
  * @brief  设置系统标志
  *
  * @param flag：SYS_FLAG_TAMPER_ALARM 防撬报警标志
  *              SYS_FLAG_ARMING_ALARM 布防报警标志
  *              SYS_FLAG_ARMING_STATUS 布防状态
  *              SYS_FLAG_ANTI_LOCK_STATUS 反锁状态
  *
  * @param state：true： 设置对应标志
  *               false：清除对应标志
  */
static bool ATE_SetSysFlag(uint8_t flag, bool state)
{
    uint8_t sys_flag = 0;
    OSAL_NvRead(SYS_OFFSET(sys_flag), &sys_flag, 1);
    if (state == true)
    {
        sys_flag |= flag;
    }
    else
    {
        sys_flag &= ~(flag);
    }

    if (OSAL_NvWrite(SYS_OFFSET(sys_flag), &sys_flag, 1) != ERROR)
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
  * @brief  恢复出厂设置
  *
  * @note
  */
static uint8_t ATE_Recovery(void)
{
    ATE_MAIN_LOG("ATE_Recovery\r\n");
    ATE_NvReset();
    return CMD_EXE_OK;
}

/**
  * @brief  恢复出厂设置
  *
  * @note   SHA1(13字节eSN + 24字节BLEkey字符串大写)
  */
static uint8_t ATE_EepromRecovery(uint8_t *pData, uint8_t len)
{
    ATE_MAIN_LOG("ATE_EepromRecovery\r\n");
    if (len != 20)
    {
        return CMD_EXE_ERR;
    }
    /* 计算本地sha1 */
    uint8_t ble_pwd[12] = {0};
    uint8_t src_data[38] = {0};
    uint8_t dst_data[21] = {0};
    OSAL_NvRead(SYS_OFFSET(eSN), &src_data, 13);
    OSAL_NvRead(SYS_OFFSET(bleKey), ble_pwd, 12);
    for (int i = 0; i < 12; i++)
    {
        sprintf((char *)&src_data[13 + 2 * i], "%02X", ble_pwd[i]);
    }
    OSAL_Crypto(CALC_SHA1, src_data, strlen((char *)src_data), dst_data, NULL);

    /* 比较sha值，一致则清空eeprom */
    if (memcmp(pData, dst_data, 20) == 0)
    {
        uint8_t init = 0;
        OSAL_NvWrite(SYS_OFFSET(nvInitFlag), &init, sizeof(init));
        OSAL_SystemReset(2000);
        return CMD_EXE_OK;
    }

    return CMD_EXE_ERR;
}
#ifndef WIFI_TYPE_XUNMEI
//typedef struct 
//{
//    uint8_t type;
//    uint8_t len;
//    uint8_t data[];
//}ServerInfo_Data_t;

//static uint8_t ATE_WrServiceInfo(uint8_t *pData, uint8_t len,uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
//{
//    ATE_MAIN_LOG("ATE_WrServiceInfo\r\n");
//    *pAckDataLen = 0;
//    if (pData[0] == 0x00)/* 写 */
//    {
//        uint8_t array_num = pData[1];/* 后面参数的种类 */
//        uint8_t offset = 0;/* 偏移量 */
//        for (int i = 0;i < array_num;i++)
//        {
//            ServerInfo_Data_t *param = (ServerInfo_Data_t *)&pData[2 + offset];
//            if (param->type == 0x01)/* 证书服务器地址 */
//            {
//                if (param->len > 200-1)
//                {
//                    return CMD_EXE_ERR;
//                }
//                uint8_t tmp[200] = {0};
//                memcpy(tmp,param->data, param->len);
//                OSAL_NvWrite(SYS_OFFSET(https_server),tmp, 200);
//            }
//        #ifdef WIFI_SUB_DEVICE || defined(CAMERA_SUB_DEVICE)
//            else if (param->type == 0x02)/* 端口 */
//            {
//                if (param->len != 2)
//                {
//                    return CMD_EXE_ERR;    
//                }
//                OSAL_NvWrite(SYS_OFFSET(mqtt_port),param->data, 2);  
//            }
//        #endif

//        #ifdef CAMERA_SUB_DEVICE
//            else if (param->type == 0x03)/* 国家码 */
//            {
//                if (param->len != 2)
//                {
//                    return CMD_EXE_ERR;    
//                }
//                OSAL_NvWrite(SYS_OFFSET(country_code),param->data, 2);  
//            }
//            else if (param->type == 0x04)/* 品牌 */
//            {
//                if (param->len != 1)
//                {
//                    return CMD_EXE_ERR;    
//                }
//                OSAL_NvWrite(SYS_OFFSET(brand),param->data, 1);    
//            }
//        #endif
//            offset += param->len + 2;   
//        }
//        return CMD_EXE_OK;
//    }
//    else if (pData[0] == 0x01)/* 读 */
//    {
//        pAckDataBuf[0] = 0x04;
//        uint8_t offset_r = 1;
//        uint8_t https_server_url[200] = {0};
//        OSAL_NvRead(SYS_OFFSET(https_server),https_server_url, 200);
//        int len = strlen(https_server_url);
//        pAckDataBuf[1] = 0x01;/* 证书服务器地址 */
//        offset_r += 1;
//        pAckDataBuf[offset_r] = (uint8_t)len;
//        offset_r += 1;
//        memcpy(&pAckDataBuf[offset_r],https_server_url,len);
//        offset_r += len;

//    #ifdef WIFI_SUB_DEVICE || defined(CAMERA_SUB_DEVICE)
//        pAckDataBuf[offset_r] = 0x02;/* 端口 */
//        offset_r += 1;
//        pAckDataBuf[offset_r] = 2;
//        offset_r += 1;
//        OSAL_NvRead(SYS_OFFSET(mqtt_port),&pAckDataBuf[offset_r], 2);
//        offset_r += 2;
//    #else
//        pAckDataBuf[0] -= 1;   
//    #endif

//    #ifdef CAMERA_SUB_DEVICE
//        pAckDataBuf[offset_r] = 0x03;/* 国家码 */
//        offset_r += 1;
//        pAckDataBuf[offset_r] = 2;
//        offset_r += 1;
//        OSAL_NvRead(SYS_OFFSET(country_code),&pAckDataBuf[offset_r], 2);
//        offset_r += 2;

//        pAckDataBuf[offset_r] = 0x04;/* 品牌 */
//        offset_r += 1;
//        pAckDataBuf[offset_r] = 1;
//        offset_r += 1;
//        OSAL_NvRead(SYS_OFFSET(brand),&pAckDataBuf[offset_r], 1);
//        offset_r += 1;
//    #else
//        pAckDataBuf[0] -= 2;   
//    #endif
//        *pAckDataLen = offset_r;
//        return CMD_EXE_OK;
//    }
//    return CMD_EXE_ERR;
//}
#else
typedef struct 
{
    uint8_t type;
    uint8_t len;
    uint8_t data[];
}ServerInfo_Data_t;

static uint8_t ATE_XMServiceInfo(uint8_t *pData, uint8_t len,uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("ATE_XMServiceInfo\r\n");
    *pAckDataLen = 0;
    if (pData[0] == 0x00)/* 写 */
    {
        ServerInfo_Data_t *param = (ServerInfo_Data_t *)&pData[2];
        if (param->type == 0x01)/* 根证书地址 */
        {
            if (param->len > 200-1)
            {
                return CMD_EXE_ERR;
            }
            uint8_t tmp[200] = {0};
            memcpy(tmp,param->data, param->len);

            ATE_RemoteXm_Send(TX_CMD_XM_SET_BOOT_ADDR, tmp, param->len, COMMAND);
        }

        return CMD_EXECUTING;
    }
    else if (pData[0] == 0x01)/* 读 */
    {
        ATE_RemoteXm_Send(TX_CMD_XM_READ_BOOT_ADDR, NULL, 0, COMMAND); // 获取证书服务器地址
        *pAckDataLen = 0;
        return CMD_EXECUTING;
    }
    return CMD_EXE_ERR;
}
#endif
/**
  * @brief  加速度传感器测试
  *
  * @note
  */
static uint8_t ATE_GsensorTest(void)
{
    uint8_t ret;
    //TODO 注意需要修改为回调接收？？？
    // ret = SYS_CALL(Gsensor_self_test);
  //  Gsensor_M_Self_Test();

    if (ret == SUCCESS)
    {
        return CMD_EXE_OK;
    }
    else
    {
        return CMD_EXE_ERR;
    }
}

/**
  * @brief  门磁回调函数
  *
  * @note
  */
static void Local_MsensorMsgCb(void *msg, uint16_t len)
{
    uint8_t data[2] = {0};
    MsensorMsg_t *msensor = (MsensorMsg_t *)msg;
    switch (msensor->action)
    {
    case MSENSOR_SELF_TEST:
        data[0] = msensor->res == 0x00 ? CMD_EXE_OK : CMD_EXE_ERR;
        data[1] = msensor->res;
        ExtKds_Send(CMD_MSENSOR_TEST, &data, 2, NULL); //发送ACK
        break;
    default:
        break;
    }
}

/**
 * @brief: 组合版本号放到版本号数组中
 * @note 格式: prefix_Num_Version
 * @param *prefix 前缀
 * @param devNum 设备号
 * @param *versionNum 版本号
 * @param *temp 组合放的位置
 */
static uint8_t ATE_PackageVersion(uint8_t *prefix, DFU_DevNum_enum_t devNum, uint8_t *versionNum, uint8_t *temp)
{
    if (versionNum[0] != '\0')
    {
        sprintf((char *)temp, "%s_%d_%s", prefix, devNum, versionNum);
        ATE_MAIN_LOG("[devNum: %d, version: %s]\r\n", devNum, temp);
        return strlen((char *)temp);
    }
    else
    {
        ATE_MAIN_LOG("[devNum: %d, version is NULL]\r\n", devNum);
        memset(temp, 0, 24);
        return 0;
    }
}

/**
  * @brief  读取人脸模组版本号
  * 
  */
static uint8_t ATE_ReadFaceVersion(uint8_t *pAckDataBuf)
{
    uint8_t pFaceBuf[20] = {0};
    uint8_t pBuf[6] = {0};
    uint8_t pFaceLen = 0;
    SYS_CALL(Face_Read_Version, pFaceBuf, &pFaceLen);
    SYS_CALL(Face_Read_Model, pBuf);
    return ATE_PackageVersion(pBuf, DFU_DEVNUM_FACE_MODULE, pFaceBuf, pAckDataBuf);
}

/**
  * @brief  读取板子版本号
  * 
  */
static uint8_t ATE_ReadBoardVersion(DFU_DevNum_enum_t devNum, uint8_t *pAckDataBuf)
{
    uint8_t version[8] = {0}; // 存放版本号
    uint8_t local_model[8] = {0}; // 存放型号
    uint8_t local_type[8] = {0};
    uint8_t pBoardBuf[20] = {0}; // 存放组合好的内容
    uint8_t pLen = 0;

    DFU_GetVersion(devNum, version);
    DFU_GetModel(devNum, local_model, local_type, 5);
    if (version[0] != '\0')
    {
        pBoardBuf[0] = version[0];
        pBoardBuf[1] = version[1];
        pBoardBuf[2] = '.';
        pBoardBuf[3] = version[2];
        pBoardBuf[4] = version[3];
        pBoardBuf[5] = '.';
        pBoardBuf[6] = version[4];
        pBoardBuf[7] = version[5];
        pBoardBuf[8] = version[6];
        
        ATE_MAIN_LOG("pBoardBuf: %s\r\n", pBoardBuf);
        pLen = ATE_PackageVersion(local_model, devNum, pBoardBuf, pAckDataBuf);
        return pLen;
    }
    else
    {
        ATE_MAIN_LOG("[devNum: %d, version is NULL]\r\n", devNum);
        return pLen;
    }
}

/**
  * @brief  读取语音模组版本
  * 
  */
static uint8_t ATE_ReadAudioVersion(uint8_t *pAckDataBuf)
{
    uint8_t pAudioBuf[10] = {0};
    uint8_t pBuf[6] = {"AUDIO"}; /// 存放esn
    Audio_GetVersion(pAudioBuf);
    return ATE_PackageVersion(pBuf, DFU_DEVNUM_AUDIO_FLASH, pAudioBuf, pAckDataBuf);
}

/**
  * @brief  读取讯美模组版本
  * 
  */
static uint8_t ATE_ReadXMVersion(DFU_DevNum_enum_t devNum, uint8_t *pAckDataBuf)
{
    uint8_t offect = 0;
    if (devNum == DFU_DEVNUM_VIDEO_MCU)
        offect = 1;
    else if(devNum == DFU_DEVNUM_WIFI_MODULE)
        offect = 2;
    else if(devNum == DFU_DEVNUM_SCREEN)
        offect = 3;
    else if(devNum == DFU_DEVNUM_RADAR)
        offect = 4;
    memcpy(pAckDataBuf, &xmVersions[offect * 24], 24);
    ATE_MAIN_LOG("[XM %d MODE:  %s]\r\n", devNum, pAckDataBuf);
    return strlen((char *)pAckDataBuf);
}

#if defined(FINGERVEIN_SUPPORT)
/**
  * @brief  读取指静脉模组版本号
  * 
  */
static uint8_t ATE_ReadFingerveinVersion(DFU_DevNum_enum_t devNum, uint8_t *pAckDataBuf)
{
    uint8_t fingerveinModel[6] = {0}; // 存放型号
    uint8_t fvnVersion[10] = {0};

    Fingervein_GetModel(fingerveinModel);
    Fingervein_GetVersion(fvnVersion);

    return ATE_PackageVersion(fingerveinModel, devNum, fvnVersion, pAckDataBuf);
}
#endif

#if defined(LOCK_TDKSENSOR_DEVICE)
/**
  * @brief  读取TDK超声波模组版本号
  * 
  */
static uint8_t ATE_ReadTDKSensorVersion(DFU_DevNum_enum_t devNum, uint8_t *pAckDataBuf)
{
    uint8_t version[5] = {0}; // 存放读取的版本号
    uint8_t pTDKBuf[10] = {0};
    uint8_t pBuf[6] = {"TDK"}; /// 存放esn
    SYS_CALL(tdkmodel_read_softversion, version);

    pTDKBuf[0] = 'V';
    pTDKBuf[1] = '1';
    pTDKBuf[2] = '.';
    pTDKBuf[3] = version[0];
    pTDKBuf[4] = version[1];
    pTDKBuf[5] = '.';
    pTDKBuf[6] = version[2];
    pTDKBuf[7] = version[3];

    return ATE_PackageVersion(pBuf, devNum, pTDKBuf, pAckDataBuf);
}
#endif

static uint8_t ATE_ReadPvnVersion(DFU_DevNum_enum_t devNum, uint8_t *pAckDataBuf)
{
    uint8_t pBuf[4] = "PVN";
    uint8_t ver[10] = {0};
    PalmVein_GetVersion(ver);
    return ATE_PackageVersion(pBuf, devNum, ver, pAckDataBuf);
}


/**
  * @brief  读指定版本号
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @note 1： WIFI模块
          2： WIFI锁
          3： 人脸模组
          4： 视频模组
          5： 视频模组MCU
          6： 前板
          7： 后板
          8： 语音FLASH
          9： 显示屏解码板
          10：感应把手
          11：门磁（门窗感应器）
          12：遥控器
          13：键盘
          14：网关
          15: UVC摄像头
          16：指静脉
  * @retval 执行结果
  */
static uint8_t ATE_ReadAnyVersion(DFU_DevNum_enum_t devNum, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("devNum: %d\r\n", devNum);
    switch(devNum)
    {
#if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
        case DFU_DEVNUM_WIFI_MODULE: // 1
#endif
        case DFU_DEVNUM_WIFI_LOCK: // 2
        case DFU_DEVNUM_FRONT_MCU: // 6
        case DFU_DEVNUM_REAR_MCU: // 7
        case DFU_DEVNUM_DOOR_SENSOR: // 11
        case DFU_DEVNUM_KEYFOB: // 12
        case DFU_DEVNUM_KEYPAD: // 13
        case DFU_DEVNUM_GATEWAY: // 14
        case DFU_DEVNUM_LCD://21
            *pAckDataLen = ATE_ReadBoardVersion(devNum, pAckDataBuf);
            break;
        case DFU_DEVNUM_AUDIO_FLASH: // 8
            *pAckDataLen = ATE_ReadAudioVersion(pAckDataBuf);
            break;
        case DFU_DEVNUM_FACE_MODULE: // 3
            *pAckDataLen = ATE_ReadFaceVersion(pAckDataBuf);
            break;

    #ifdef CAMERA_SUB_DEVICE
        case DFU_DEVNUM_VIDEO_MODULE: // 4  
        {
            if (video_ver[0] != 0)/* 版本缓存不为空 */
            {
                *pAckDataLen = strlen(video_ver);
                memcpy(pAckDataBuf,video_ver,strlen(video_ver));
                break;
            }
            else
            {
                Camera_LcdCtrl(SYS_CALL(Local_Get_DispLogo), 10, 100, 2);/* 开5713电源 */
                *pAckDataLen = 0;
                return CMD_EXECUTING;
            }
        }
        case DFU_DEVNUM_UVC:
        {
            if (uvc_ver[0] != 0)/* 版本缓存不为空 */
            {
                *pAckDataLen = strlen(uvc_ver);
                memcpy(pAckDataBuf,uvc_ver,strlen(uvc_ver));
                break;
            }
            else
            { 
                Camera_LcdCtrl(SYS_CALL(Local_Get_DispLogo), 10, 100, 2);/* 开5713电源 */
                *pAckDataLen = 0;
                return CMD_EXECUTING;
            }
        }
        break;
    #endif  /* END OF CAMERA_SUB_DEVICE */

    #if defined(WIFI_TYPE_XUNMEI)
        case DFU_DEVNUM_WIFI_MODULE: // 1
        case DFU_DEVNUM_VIDEO_MODULE: // 4

        case DFU_DEVNUM_VIDEO_MCU: // 5
        case DFU_DEVNUM_SCREEN: // 9
        case DFU_DEVNUM_RADAR:  //
            *pAckDataLen = ATE_ReadXMVersion(devNum, pAckDataBuf);
            break;
    #endif
        case DFU_DEVNUM_TOUCH_HANDLE: // 10
        {
            uint8_t pBuf[6] = {"SENSE"}; /// 存放esn
            *pAckDataLen = ATE_PackageVersion(pBuf, devNum, handle_version, pAckDataBuf);
        }
            break;
#if defined(FINGERVEIN_SUPPORT)
        case DFU_DEVNUM_FINGERVEIN: // 16
        {
            *pAckDataLen = ATE_ReadFingerveinVersion(devNum, pAckDataBuf);
        }
            break;
#endif

#if defined(LOCK_TDKSENSOR_DEVICE)
        case DFU_DEVNUM_TDKUS: // 20
        {
            //< 读TDK模组版本
            *pAckDataLen = ATE_ReadTDKSensorVersion(devNum, pAckDataBuf);
        }
            break;
#endif
        case DFU_DEVNUM_PVN://掌静脉
            *pAckDataLen = ATE_ReadPvnVersion(devNum, pAckDataBuf);
        break;
        #ifdef FINGER_MODULE
        case DFU_DEVNUM_FP:
            Finger_GetVersion(pAckDataBuf);
            *pAckDataLen= 15;
        break;
        #endif
    }
    
    ATE_MAIN_LOG("pAckDataBuf:%s, pAckDataLen: %d\r\n", pAckDataBuf, *pAckDataLen);
    if (*pAckDataLen != 0)
        return CMD_EXE_OK;
    else
        return CMD_EXE_ERR;
}

/**
  * @brief  读故障码
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval uint8_t
  */
static uint8_t ATE_ReadErrorCode(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("ATE_ReadErrorCode: %08x\r\n", err_code);
    memset(pAckDataBuf, 0, sizeof(err_code));
    memcpy(pAckDataBuf, (uint8_t *)&err_code, sizeof(err_code));
    *pAckDataLen = sizeof(err_code);
    return CMD_EXE_OK;
}


static uint8_t ATE_XunmeiDevTest(uint8_t*pData)
{
    // switch (pData[0])
    // {
    //     case  0://测试MIC(启动录音3s)
    //     break;
    //     case  1://测试摄像头，扫固定二维码读取信息确认 (扫描成功后结果通过 0x1A 上报)
    //     break;
    //     case  2://测试 PIR(检测到距离后通过 0X1B 主动上报)
    //     break;
    //     case  3://声音测试(收到此命令后播放先前录制的语音) 
    //     break;
    //     case  4://开启红外补光灯测试
    //     break;
    //     case  5://关闭红外补光灯测试
    //     break;
    //     case  6://测试留言 mic (启动录音 3s)
    //     break;
    //     case  7://留言播放测试(收到次命令播放录制的留言)
    //     break;
    //     case  8://雷达测试
    //     break;
    //     case  9://雷达打开
    //     break;
    //     case  10://雷达关闭
    //     break;
    //     default:
    //     break;
    // }
    xunmei_peripherals_cmd = CMD_XUNMEI_DEV_TEST;
    xunmei_peripherals_type = pData[0];
    ATE_MAIN_LOG("TX_CMD_XM_MODULE_TEST :%02x \r\n",pData[0]);
    ATE_RemoteXm_Send(TX_CMD_XM_MODULE_TEST, &pData[0], 1, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  设置产测模式
  *
  * @param  mode：模式
  */
static void ATE_SetProductionTestMode(TestMode_enum_t mode)
{
    ATE_MAIN_LOG("ATE_SetProductionTestMode mode :%02X\r\n", mode);
    if (mode == TESTMODE_AGING)
    {
        ATE_SetSysFlag(SYS_FLAG_AGING_STATUS, true);
    }
    else
    {
        ATE_SetSysFlag(SYS_FLAG_AGING_STATUS, false);
    }

    if (mode == TESTMODE_TESTING)
    {
        SYS_CALL(XunMei_Power, SET); // 产测前给讯美模组上电
    }

    productionTestMode = mode;
    if (productionTestMode == TESTMODE_TESTING || productionTestMode == TESTMODE_AGING) //产测模式下，不自动休眠
    {
        OSAL_AppStateSet("APP_LOCAL", DISABLE);
        OSAL_AppStateSet("APP_BLE", DISABLE);
        OSAL_AppStateSet("APP_REMOTE", DISABLE);
        /* 建议同一个类型的app不要起那么多的名字，用通用的名字 */
        OSAL_AppStateSet("REMOTE_XM_LOCAL", DISABLE);
        OSAL_AppStateSet("APP_LOCAL_REV", DISABLE);
        OSAL_AppStateSet("BLE_LOCAL", DISABLE);
        OSAL_AppStateSet("REMOTE_APP", DISABLE);
        OSAL_AppStateSet("APP_LOCAL_PLUS", DISABLE);
        OSAL_AppStateSet("BLE_Main", DISABLE);


        TimerHandle_stu_t ATETestTimer = NULL;
        ATETestTimer = OSAL_TimerCreate(ATE_test_process_cb, ATE_AGING_TIMER, SET);
        OSAL_TimerSet(ATETestTimer, TIM_RUN_ONLY_WAKE); //设置定时器仅唤醒状态工作

        OSAL_UpdateSleepTime(0XFFFFFFFF, 0);
        ATE_MAIN_LOG("productionTestMode:%02X\r\n", productionTestMode);
    }
}

/**
  * @brief  获取当前产测模式
  *
  * @return 返回当前工作模式
  */
TestMode_enum_t ATE_GetProductionTestMode(void)
{
    if (productionTestMode == TESTMODE_UNKNOW)
    {
        uint8_t m_sys_flag = 0;
        OSAL_NvRead(SYS_OFFSET(sys_flag), &m_sys_flag, 1);
        if ((m_sys_flag & SYS_FLAG_AGING_STATUS) && (m_sys_flag !=0xff) )
        {
            productionTestMode = TESTMODE_AGING;
        }
        else
        {
            productionTestMode = TESTMODE_NORMAL;
        }
    }
    // ATE_MAIN_LOG("ATE_GetProductionTestMode mode :%02X\r\n",productionTestMode);
    return productionTestMode;
}

static void ATE_ReportStatus(uint8_t status, TestMode_enum_t mode)
{
    uint8_t statusBuffer[2] = {0};
    statusBuffer[0] = status;
    statusBuffer[1] = (uint8_t)mode;
    ExtKds_Send(CMD_LOCK_STATUS_REPORT, statusBuffer, 2, extend_kds_send_callback); //上报
}

 /**
  * @brief  设置下次上电自学习方向标志
  *
  * @return 执行结果
  */
static uint8_t ATE_SetAutoCalFlag(uint8_t *pData)
{   
    if(*pData == SET)
    {
        uint8_t dataBuff[1] = {0};
//        test_type = SET_AUTO_CAL_FLAG_MODE;
//        Lock_TestCtrl(SET_AUTO_CAL_FLAG_MODE, dataBuff, 0);
        return CMD_EXE_OK;
    }

    return CMD_EXE_ERR;    
}
/**
  * @brief  门锁模式切换
  * @param  pData：数据域指针
  * @retval 执行结果
  */
static uint8_t ATE_ChangeWorkMode(uint8_t *pData)
{
    ATE_MAIN_LOG("ATE_ChangeWorkMode pData[0]:%02X\r\n", pData[0]);
    if (pData[0] == 0)
    {
        ATE_SetProductionTestMode(TESTMODE_NORMAL);
        SYS_CALL(Card_SetWorkMode, CARD_MODE_VERIFY);

        #ifdef DL5
        //老化完成切回正常模式要清空校准值
        LockBigPro_Reset();
        #endif
    }
    else if (pData[0] == 1)
    {
        if (productionTestMode == TESTMODE_NORMAL && OSAL_GetTickCount() > 10000)
        {
            ATE_MAIN_LOG("ATE curTick: %ld\r\n", OSAL_GetTickCount());
            return CMD_EXE_ERR; //上电5s内才允许切换到产测模式
        }
        ATE_MAIN_LOG("\r\n\r\n\r\n\r\nATE_ChangeWorkMode Product Mode\r\n\r\n\r\n\r\n");
        ATE_SetProductionTestMode(TESTMODE_TESTING);
        SYS_CALL(dsensor_set_demo_mode, 1);
        SYS_CALL(XunMei_Power, SET);
        OSAL_MessageSubscribe(app_handle, COMP_IRSENSOR, ATE_IrSensorCb);
        OSAL_MessageSubscribe(app_handle, COMP_TOUCH, ATE_TouchMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_CARD, ATE_CardMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_FINGER, ATE_FingerMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_FINGERVEIN, ATE_FingerveinMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_FACE, ATE_FaceMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_DSENSOR, ATE_DSensorMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_XUNMEI, ATE_XunmeiMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_PSENSOR, ATE_LockPsensorMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_LOCK, ATE_LockMsgCb);
        OSAL_MessageSubscribe(app_handle, COMP_WIFI, ATE_WifiMsgCb);
        OSAL_MessageSubscribe(app_handle,COMP_MSENSOR, Local_MsensorMsgCb);
        OSAL_MessageSubscribe(app_handle,COMP_PALMVEIN,ATE_PvnMsgCb);
    #ifdef CAMERA_SUB_DEVICE
        OSAL_MessageSubscribe(app_handle, COMP_PIR, ATE_PirCb);
    #endif  /* END OF CAMERA_SUB_DEVICE */
        SYS_CALL(Card_SetWorkMode, CARD_MODE_ADD);

        ATE_RemoteXm_Send(TX_CMD_XM_VERSION, NULL, 0, COMMAND); // 获取1459版本信息

    /* 蓝牙短连接设备开广播 */
    #if defined(BLE_SHORT_CONNECTION)
        SYS_CALL(BleApp_KeepAlive);
    #endif
    }
    else if (pData[0] == 2)
    {
        ATE_SetProductionTestMode(TESTMODE_AGING);
        SYS_CALL(Card_SetWorkMode, CARD_MODE_VERIFY);

        #ifdef DL5
        //老化模式先校准   LOCKED_DIR_LEFT  LOCKED_DIR_RIGHT
        LockBigPro_SetRange(LOCKED_DIR_RIGHT);
        #endif 
    }
    else
    {
        return CMD_EXE_ERR;
    }
    return CMD_EXE_OK;
}

/**
  * @brief  设置门锁参数
  * @brief  pData：数据域指针
  * @brief  dataLen：数据长度
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
static uint8_t ATE_SetDoorLockPara(uint8_t *pData, uint8_t dataLen, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("ATE_SetDoorLockPara\r\n");
    uint8_t ret = SUCCESS;
    *pAckDataLen = 0;
    if (pData[0] == 0x00) //写
    {
		uint8_t array_num = pData[1];
        uint8_t *pos = pData + 2;
        SYS_CALL(Users_SetAteFlag, ERROR);
        for (int i = 0; i < array_num; i++)
        {
            uint8_t type = pos[0];
            uint8_t len = pos[1];
            uint16_t keys_num = *(uint16_t *)(pos +2);
            ATE_MAIN_LOG("type: %02x, len: %d, keys_num: %d\r\n", type, len, keys_num);
            if (type == USERS_TYPE_FVN)
            {
            #if defined(FINGERVEIN_SUPPORT)
                ret = SYS_CALL(Users_SetKeysQty, type, keys_num);
            #endif
            }
            else
            {
                if (type == USERS_TYPE_PWD)
                {
                    if (len >= 4)
                    {
                        uint16_t ploy_keys_num = *(uint16_t *)(pos + 4);
                        keys_num += ploy_keys_num;
                        ret = SYS_CALL(Users_SetKeysQty, USERS_TYPE_PLOY_PWD, ploy_keys_num); //设置策略密钥数量
                    }
                }
                if (ret != ERROR)
                {
                    ret = SYS_CALL(Users_SetKeysQty, type, keys_num);
                }
            }
			pos += (len + 2);
            if (ret != SUCCESS)
            {
                break;
            }
        }
        if (ret == SUCCESS) //全部写入成功后存储产品标志
        {
            ret = SYS_CALL(Users_SetAteFlag, SUCCESS);
        }
        return (ret == SUCCESS ? 0x80 : 0x81);
    }
    else if (pData[0] == 0x01) //读
    {
        uint8_t type_table[6] = {USERS_TYPE_PWD, USERS_TYPE_CARD, USERS_TYPE_FPT, USERS_TYPE_FACE, USERS_TYPE_FVN,USERS_TYPE_PVN};
        pAckDataBuf[0] = sizeof(type_table);
        uint8_t *pos = pAckDataBuf + 1;
        for (int i = 0; i < pAckDataBuf[0]; i++)
        {
            uint8_t type = type_table[i];
            uint8_t len = 0x02;
			uint16_t keys_num = SYS_CALL(Users_GetKeysQty, type);

            if (type == USERS_TYPE_PWD)
            {
                len = 0x04;
                uint8_t ploy_keys_num = SYS_CALL(Users_GetKeysQty, USERS_TYPE_PLOY_PWD);
                keys_num -= ploy_keys_num;
                pos[4] = ploy_keys_num & 0xff;
                pos[5] = (ploy_keys_num >> 8) & 0xff;
            }

            pos[0] = type;
            pos[1] = len;
            pos[2] = keys_num & 0xff;
            pos[3] = (keys_num >> 8) & 0xff;
            pos += (len + 2);
        }
		*pAckDataLen = (pos - pAckDataBuf);
    }
    return 0x80;
}

/**
  * @brief  蓝牙频偏校准
  * @param  pData：数据域指针
  * @param  len：数据长度
  * @retval 执行结果
  */
static uint8_t ATE_BleCal(uint8_t *pData, uint8_t dataLen, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    Ble_SetOffsetCal(pData);
    pAckDataBuf[0] = 0x00;
    memcpy(&pAckDataBuf[1], bleMacSaveAddr, 6);
    Ble_GetGATT(&pAckDataBuf[7]);
    *pAckDataLen = 10;
    return CMD_EXE_OK;
}

/**
  * @brief  蓝牙RF定频测试
  * @param  pData：数据域指针
  * @param  len：数据长度
  * @retval 执行结果
  */
static uint8_t ATE_BleFreTest(uint8_t *pData, uint8_t len)
{
    Ble_SetRadioFreqen(pData);
    return CMD_EXE_OK;
}

static uint8_t ATE_ExtendNetworkSet(uint8_t *pData)
{
    uint8_t ret = CMD_EXE_ERR; 
    if(pData[0] == 0x01)//ZWAVE模块
    {
        switch(pData[1])
        {
//            case CONNECT_NETWORK://入网
//            case DISCONNECT_NETWORK://退网
            //SYS_CALL(Remote_ConnectNetwork, pData[1]);   
            ret = CMD_EXE_OK;
                break;
            default:break;  
        }
    }
    return  ret;
    
}

/**
  * @brief  指静脉测试
  * @retval 执行结果
  */
static uint8_t ATE_FvnTest(void)
{
    test_type = FVN_TEST;
    ATE_MAIN_LOG("ATE_FvnTest\r\n");
    SYS_CALL(Fingervein_Start_Ate_Test);
    return CMD_EXE_OK;
}

/**
  * @brief  读门锁电压
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
static uint8_t ATE_ReadLockVoltage(uint8_t *pData,uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    if(newBatTestFlag == 0)
    {
        *pAckDataLen = 1;
        *pAckDataBuf = (uint8_t)SYS_CALL(Battery_Get);
        ATE_MAIN_LOG("ATE_ReadLockVoltage :%d \r\n", *pAckDataBuf);
    }
    else
    {
        #ifdef BAT_ENCRY
        if(pData[0] == 0x01)
        {
            *pAckDataLen = sizeof(ATE_Bat_Encrypt_t);
            memcpy(pAckDataBuf,&AteBatInfo,sizeof(ATE_Bat_Encrypt_t));
            ATE_MAIN_LOG("enc bat read\r\n");
        }
        #endif
    }

    return CMD_EXE_OK;
}

/**
  * @brief  按键测试
  * @retval 执行结果
  */
static uint8_t ATE_TouchTest(void)
{
    test_type = KEY_TEST;
    uint8_t dataBuff[1] = {0};
    ATE_MAIN_LOG("ATE_TouchTest\r\n");
//    Optocoupler_Ctrl(0);//开光耦
//    Lock_TestCtrl(KEY_TEST_MODE, dataBuff, 0);
    return CMD_EXE_OK;
}

/**
  * @brief  指纹测试
  * @retval 执行结果
  */
static uint8_t ATE_FptTest(void)
{
    test_type = FPT_TEST;
//    Finger_SetLed( FPT_LED_STOP );
    ATE_MAIN_LOG("ATE_FptTest\r\n");
    return CMD_EXE_OK;
}

/**
  * @brief  卡片测试
  * @retval 执行结果
  */
static uint8_t ATE_CardTest(void)
{
    test_type = CARD_TEST;
    ATE_MAIN_LOG("ATE_CardTest\r\n");
    return CMD_EXE_OK;
}

/**
  * @brief  锁体测试
  * @param  pData：数据域指针
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
static uint8_t ATE_LockBodyTest(uint8_t *pData, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    uint8_t dataBuff[1] = {0};
    ATE_MAIN_LOG("ATE_LockBodyTest,%d", pData[0]);//ATE_LOG_D
    if (pData[0] == 0x00) //开锁
    {
        test_type = UNLOCK_TEST;
        dataBuff[0] = LOCK_CTRL_UNLOCK;
        Lock_TestCtrl(LOCK_UNLOCK_TEST_MODE, dataBuff, 1);
    }
    else if (pData[0] == 0x01) //关锁
    {
        test_type = LOCKED_TEST;
        dataBuff[0] = LOCK_CTRL_LOCKED;
        Lock_TestCtrl(LOCK_UNLOCK_TEST_MODE, dataBuff, 1);
    }
    else if(pData[0] == 0x02) //自学习
    {
        test_type = MOTOR_TEST_MODE;
        dataBuff[0] = 0;
        Lock_TestCtrl(MOTOR_TEST_MODE, dataBuff, 0); 
    }
    else if(pData[0] == 0x03) //检测光耦挡片
    {
        test_type = HALL_OC_TEST_MODE;
        dataBuff[0] = 0;
        Lock_TestCtrl(HALL_OC_TEST_MODE, dataBuff, 0); 
    }
    else if (pData[0] == 0x04) //停止
    {
        test_type = LOCK_STOP_TEST;
        dataBuff[0] = LOCK_CTRL_STOP;
        Lock_TestCtrl(LOCK_UNLOCK_TEST_MODE, dataBuff, 1);
    }
    return CMD_EXECUTING;
}

/**
  * @brief  版本号查询
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
static uint8_t ATE_ReadSoftVersion(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    // uint8_t model[10] = {0};
    // OSAL_NvRead(SYS_OFFSET(model), model, 10);
    *pAckDataLen = 15;
    memset(pAckDataBuf, 0, 15);
    strcpy((char *)pAckDataBuf, FIRMWARE_VER);
    // strcpy((char *)(pAckDataBuf + 8), (char *)model);
    ATE_MAIN_LOG("SoftVersion:%s", pAckDataBuf);
    return CMD_EXE_OK;
}

/**
  * @brief  感应把手版本号查询
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
// static uint8_t ATE_ReadHandleVersion(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
// {
//     *pAckDataLen = 10;
//     memset(pAckDataBuf, 0, 10);
//     memcpy(pAckDataBuf, handle_version, 4);
//     ATE_MAIN_LOG("ATE_ReadSoftVersion\r\n");
//     return CMD_EXE_OK;
// }

/**
  * @brief  读取防伪码
  *
  * @param  pStr：数据指针
  * @return 成功返回激活码长度, 失败返回0
  */
static uint8_t ATE_ReadSecurityCode(uint8_t *pStr)
{
    uint8_t tmpBuf[32] = {0}, i;
    ATE_MAIN_LOG("ATE_ReadSecurityCode\r\n");
    OSAL_NvRead(SYS_OFFSET(systemCode), tmpBuf, 32);
    for (i = 0; i < 32; i++)
    {
        if ((tmpBuf[i] >= '0' && tmpBuf[i] <= '9') || (tmpBuf[i] >= 'A' && tmpBuf[i] <= 'Z'))
        {
            continue;
        }
        else if (tmpBuf[i] == '\0' && i > 0)
        {
            if (pStr != NULL)
            {
                strcpy((char *)pStr, (const char *)tmpBuf);
            }
            return i;
        }
        else
        {
            ATE_MAIN_LOG("sc read bad char %d[%x]\r\n", i, tmpBuf[i]);
            return 0; //防伪码错误
        }
    }
    ATE_MAIN_LOG("sc read error\r\n");
    return 0;
}

/**
  * @brief  写防伪码
  *
  * @param  pCode：数据指针
  * @param  len：数据长度
  * @return 成功返回SUCCESS, 失败返回ERROR
  */
static ErrorStatus ATE_WriteSecurityCode(uint8_t *pCode, uint8_t len)
{
    uint8_t temp[32] = {0};
    ATE_MAIN_LOG("ATE_WriteSecurityCode\r\n");
    if (len > 26) //防伪码最大26位，长度可变
    {
        ATE_MAIN_LOG("sc write error length:%d\r\n", len);
        return ERROR;
    }

    memcpy(temp, pCode, len);
    OSAL_NvWrite(SYS_OFFSET(systemCode), temp, 32);
    memset(temp, 0, 32);
    OSAL_NvRead(SYS_OFFSET(systemCode), temp, len);
    if (memcmp(pCode, temp, len) == 0)
    {
        return SUCCESS;
    }
    ATE_MAIN_LOG("sc write error(not same)\r\n");
    return ERROR;
}

/**
  * @brief  读取激活码
  *
  * @param  pStr：数据指针
  * @return 成功返回true, 失败返回false
  */
static bool ATE_ReadActivationCode(uint8_t *pStr)
{
    uint8_t tmpBuf[20 + 1] = {0}, i;
    SYS_CALL(Users_GetActiveCode, tmpBuf);
    for (i = 0; i < sizeof(tmpBuf); i++)
    {
        if (tmpBuf[i] != 0)
        {
            break; //激活码存在
        }
    }
    if (pStr != NULL && i < sizeof(tmpBuf))
    {
        memcpy(pStr, tmpBuf, sizeof(tmpBuf));
    }

    if (i < sizeof(tmpBuf))
    {
        return true; //激活码存在
    }
    return false; //激活码不存在
}

/**
  * @brief  写激活码，将6字节激活码经过哈希后存到EEPROM
  *
  * @param  pCode：数据指针
  * @param  len：数据长度
  * @return 成功返回true, 失败返回false
  */
static bool ATE_WriteActivationCode(uint8_t *pCode, uint8_t len)
{
    uint8_t digest[20 + 1] = {0};
    if (len != 6)
    {
        return false;
    }
    if (OSAL_Crypto(CALC_SHA1, pCode, len, digest, NULL) == ERROR)
    {
        return false;
    }
    uint8_t string[7] = "";
    memcpy(string, pCode, 6);
    ATE_MAIN_LOG("NvMan_WriteActivationCode [%s]\r\n", string);
    SYS_CALL(Users_SetActiveCode, digest);
    return true;
}

/**
  * @brief  写pcbaSN
  *
  * @param  pCode：数据指针
  * @param  len：数据长度
  * @return 成功返回ture, 失败返回false
  */
static bool ATE_WritePcbaSn(uint8_t *pStr, uint8_t len)
{
    if (len > 32)
    {
        return false;
    }
    uint8_t pcbasn[32] = {0};
    memset(pcbasn, 0, 32);
    memcpy(pcbasn, pStr, len);
    OSAL_NvWrite(SYS_OFFSET(pcbaSn), pcbasn, 32);
    ATE_MAIN_LOG("pcbasn :%s\r\n", pcbasn);
    return true;
}

/**
  * @brief  读pcbaSN
  *
  * @param  pCode：数据指针
  * @param  len：数据长度
  * @return 成功返回ture, 失败返回false
  */
static uint8_t ATE_ReadPcbaSn(uint8_t *sn)
{
    uint8_t pcbasn[32] = {0};
    memset(pcbasn, 0, 32);
    OSAL_NvRead(SYS_OFFSET(pcbaSn), pcbasn, 32);
    uint8_t i = 0;
    for (i = 0; i < 32; i++)
    {
        if (pcbasn[i] == 0)
            break;
    }
    memcpy((char *)sn, pcbasn, i);
    ATE_MAIN_LOG("pcbasn :%s\r\n", pcbasn);
    return i;
}

/**
  * @brief  烧录或者读取防伪码
  * @brief  pData：数据域指针
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
static uint8_t ATE_ReadWriteSecurityCode(uint8_t *pData, uint8_t dataLen, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    uint8_t securityCode[32] = {0};
    *pAckDataLen = 0;
    ATE_MAIN_LOG("ATE_ReadWriteSecurityCode %02X\r\n", pData[0]);
    if (pData[0] == 0X10) //查询防伪码/SN
    {
        *pAckDataLen = ATE_ReadSecurityCode(securityCode);
        if (*pAckDataLen == 0)
        {
            return CMD_EXE_ERR;
        }
        memcpy(pAckDataBuf, securityCode, *pAckDataLen);
        return CMD_EXE_OK;
    }
    else if (pData[0] == 0X11) //写入防伪码/SN
    {
        if (ATE_ReadSecurityCode(NULL) > 0)
        {
            return CMD_EXE_ERR; //已经写入了
        }
        else if (dataLen - 1 <= 26 && dataLen - 1 >= 1) //防伪码长度1~26位
        {
            for (int i = 1; i < dataLen; i++)
            {
                if (!((pData[i] >= '0' && pData[i] <= '9') || (pData[i] >= 'A' && pData[i] <= 'Z')))
                {
                    return CMD_EXE_ERR;
                }
            }

            if (ATE_WriteSecurityCode(&pData[1], dataLen - 1) != SUCCESS)
            {
                return CMD_EXE_ERR;
            }
            *pAckDataLen = dataLen - 1;
            memcpy(pAckDataBuf, &pData[1], dataLen - 1);
            return CMD_EXE_OK;
        }
    }
    else if (pData[0] == 0X20) //查询激活码
    {
        if (ATE_ReadActivationCode(NULL) == false)
        {
            ATE_MAIN_LOG("ActivationCode is null\r\n");
            return CMD_EXE_ERR; //激活码不存在
        }
        else
        {
            return CMD_EXE_OK;
        }
    }
    else if (pData[0] == 0X21) //写入激活码
    {
        if (ATE_ReadActivationCode(NULL))
        {
            ATE_MAIN_LOG("ActivationCode is exist\r\n");
            return CMD_EXE_ERR; //已经写入了
        }
        else if (dataLen - 1 == 6) //激活码长度固定为6
        {
            for (int i = 1; i < 6 + 1; i++)
            {
                if (!(pData[i] >= '0' && pData[i] <= '9'))
                {
                    ATE_MAIN_LOG("ActivationCode is out of range 0-9\r\n");
                    return CMD_EXE_ERR;
                }
            }

            if (!ATE_WriteActivationCode(&pData[1], 6))
            {
                ATE_MAIN_LOG("ActivationCode is write error\r\n");
                return CMD_EXE_ERR;
            }
            *pAckDataLen = dataLen - 1;
            memcpy(pAckDataBuf, &pData[1], dataLen - 1);
            return CMD_EXE_OK;
        }
    }
    else if (pData[0] == 0x13)
    {
        if (ATE_WritePcbaSn(&pData[1], dataLen - 1))
        {
            *pAckDataLen = dataLen - 1;
            memcpy(pAckDataBuf, &pData[1], dataLen - 1);
            return CMD_EXE_OK;
        }
        return CMD_EXE_ERR;
    }
    else if (pData[0] == 0x23) //查询产测数据块
    {
        *pAckDataLen = ATE_ReadPcbaSn(securityCode);
        if (*pAckDataLen == 0)
        {
            return CMD_EXE_ERR;
        }
        memcpy(pAckDataBuf, securityCode, *pAckDataLen);
        return CMD_EXE_OK;
    }
    else if (pData[0] == 0x30) //反激活
    {
        SYS_CALL(Users_SetActiveCodeStatus, DISABLE);
        return CMD_EXE_OK;
    }
    else if (pData[0] == 0X40) //查询蓝牙SN(ESN)
    {
        uint8_t blesn[20] = {0};
        if (OSAL_NvRead(SYS_OFFSET(eSN), blesn, ESN_LENG) == SUCCESS)
        {
            memset(pAckDataBuf, 0, ESN_LENG);
            memcpy(pAckDataBuf, blesn, ESN_LENG); 
            *pAckDataLen = ESN_LENG;
            return CMD_EXE_OK;
        }
        return CMD_EXE_ERR;
    }
    return CMD_EXE_ERR; /* 指令参数错误 */
}

/**
  * @brief  读门锁时间
  * @param  pAckDataBuf：应答数据域指针
  * @param  pAckDataLen：应答数据域长度
  * @retval 执行结果
  */
static uint8_t ATE_ReadLockTime(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    *pAckDataLen = 6;
    //读门锁的RTC
    uint8_t dec_time[6];
    OSAL_TimeGet(dec_time, T_TIME);
    uint8_t bcd_time[6] = {TIME_DEC2BCD(dec_time)};
    memcpy(pAckDataBuf, bcd_time, 6);
    ATE_MAIN_LOG("ATE_ReadLockTime :%02X %02X %02X %02X %02X %02X\r\n", bcd_time[0], bcd_time[1], bcd_time[2], bcd_time[3], bcd_time[4], bcd_time[5]);
    return CMD_EXE_OK;
}

uint8_t get_sleep_flag(void)
{
    return sleep_flag;
}

void set_sleep_flag(uint8_t flag)
{
    sleep_flag = flag;
}

static uint8_t ATE_SystemSleep(uint8_t *pdata)
{
    // if (pdata[0] == 1)
    // {
    //     ATE_MAIN_LOG("xun mei low power mode\r\n");
    //     ATE_RemoteXm_SetLowPower(); //讯美模块进入功耗模式
    //     OSAL_UpdateSleepTime(1000, 0);
    // }
    // else
    //{
        ATE_MAIN_LOG("ATE_SystemSleep\r\n");
        SYS_CALL(XunMei_Power, RESET);
        OSAL_UpdateSleepTime(1000, 1);
    //}
    Led_Set("LED", LED_OFF, 0, 0);
    Led_Set("LED_LP", LED_OFF, 0, 0);
    Led_Set("LED_LOCK", LED_OFF, 0, 0);
    sleep_flag = 1;
    return CMD_EXE_OK;
}

/**
  * @brief  指示灯测试
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_KeyBoardLedTest(uint8_t *pData, uint8_t len)
{
    ATE_MAIN_LOG("ATE_KeyBoardLedTest\r\n");
    if (len >= 1 && pData[0] == 0x01)
    {
        ATE_MAIN_LOG("Cmd 0x1D %d\r\n", pData[0]);
        led_test_status = LED_TEST_OPEN_CLOSE; //通过感应把手控制开关门指示灯
    }
    else
    {
        led_test_status = LED_TEST_ALL; //测试所有LED灯（有感应把手时，主控控制开关门指示灯）
    }
    test_type = LED_TEST;
    return CMD_EXE_OK;
}

/**
  * @brief  语音测试
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_PlayAudio(uint8_t *pData, uint8_t len, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("ATE_PlayAudio\r\n");
    if (len == 1)
    {
        Audio_Play(pData[0], SET);
    }
    else if (len == 2)
    {
        Audio_Play(pData[1] << 8 | pData[0], SET);
    }
    Beep_Set(1, 2000);//5000

    *pAckDataLen = 16;
    Audio_GetVersion(pAckDataBuf);

    return CMD_EXE_OK;
}

/**
  * @brief  获取蓝牙MAC
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_ReadBleMac(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("ATE_ReadBleMac\r\n");
    memset(pAckDataBuf, 0, 6);
    memcpy(pAckDataBuf, bleMacSaveAddr, 6);
    *pAckDataLen = 6;
    return CMD_EXE_OK;
}

/**
  * @brief  读取凯迪仕wifi模组wifi和ble mac
  * @note   
  * @param  *pAckDataBuf
  * @param  *pAckDataLen
  * @return uint8_t
  */
static uint8_t ATE_ReadWifiBleMac(uint8_t type, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    uint8_t ret = CMD_EXE_ERR;
    if (type == 0x01) //读取wifi mac
    {
        ATE_MAIN_LOG("ATE_ReadKdsWifiMac\r\n");
        WiFi_ReadMac(pAckDataBuf);
        *pAckDataLen = 6;
        ret = CMD_EXE_OK;
    }
    else if(type == 0x02) // 蓝牙MAC地址
    {
        ret = ATE_ReadBleMac(pAckDataBuf, pAckDataLen);         				
    }
    return ret;
}

/**
  * @brief  获取讯美WIFI MAC
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_ReadXMWifiMac(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    ATE_MAIN_LOG("ATE_ReadXMWifiMac\r\n");
    ATE_RemoteXm_Send(TX_CMD_XM_READ_MAC, NULL, 0, COMMAND);
    return CMD_EXECUTING;

}

/**
  * @brief  写入蓝牙密钥
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_WriteBleKey(uint8_t *pData, uint8_t len, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
#ifdef KOS_PARAM_OSPORT_CRYPTO
    memcpy(bleKey, pData, len);
    if (strlen(bleESN) != 0)
        OSAL_OsportSetDefaultAccount(KOS_PARAM_DFU_ALIAS, bleESN, bleKey);
#endif
    uint8_t blekey[12] = {0};
    if (OSAL_NvWrite(SYS_OFFSET(bleKey), pData, len) == SUCCESS)
    {
        if (OSAL_NvRead(SYS_OFFSET(bleKey), blekey, len) == SUCCESS)
        {
            if (memcmp(pData, blekey, len) == 0)
            {
                ATE_MAIN_LOG("ATE_WriteBleKey blekey:%s\r\n", blekey);
                memset(pAckDataBuf, 0, len);
                memcpy(pAckDataBuf, blekey, len);
                *pAckDataLen = len;
                return CMD_EXE_OK;
            }
        }
    }
    return CMD_EXE_ERR;
}

/**
  * @brief  LED灯控制
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_LedControl(uint8_t *pData)
{
    ATE_MAIN_LOG("ATE_LedControl\r\n");
    char led[] = "LEDn";
    uint8_t swi = (pData[1] == 1) ? LED_ON : LED_OFF;

    if (pData[0] <= 9)
    {
        led[3] = pData[0] + '0';
    }
    else if (pData[0] == 10)
    {
        led[3] = '*';
    }
    else if (pData[0] == 11)
    {
        led[3] = '#';
    }
    else if (pData[0] == 0XFF)
    {
        led[3] = '\0';
    }
    else if (pData[0] == 13)
    {  
        Led_Set("LED_LOGO_R", (LedCtrlType_enum_t)swi, 0, 0);  //红灯
        return CMD_EXE_OK;
    }
    else if (pData[0] == 14)
    {
        Led_Set("LED_LOGO_B", (LedCtrlType_enum_t)swi, 0, 0);  //蓝灯
        return CMD_EXE_OK;
    }
    else if (pData[0] == 15)
    {
        Led_Set("LED_LOGO_W", (LedCtrlType_enum_t)swi, 0, 0);  //白灯
        return CMD_EXE_OK;
    }
    else if (pData[0] == 16)
    {
        Led_Set("LED_BAT", (LedCtrlType_enum_t)swi, 0, 0);  //电量灯
        return CMD_EXE_OK;
    }
    else if (pData[0] == 17)
    {
        Led_Set("LED_LP", (LedCtrlType_enum_t)swi, 0, 0);  //低电灯
        return CMD_EXE_OK;
    }
    else
    {
        return CMD_EXE_ERR;
    }
    Led_Set(led, (LedCtrlType_enum_t)swi, 0, 0);
    return CMD_EXE_OK;
}

/**
  * @brief  写入蓝牙SN
  * @note
  *
  * @return 命令执行结果
  */
static uint8_t ATE_WriteBleSN(uint8_t *pData, uint8_t len, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
#ifdef KOS_PARAM_OSPORT_CRYPTO
    memcpy(bleESN, pData, len);
    if (strlen(bleKey) != 0)
        OSAL_OsportSetDefaultAccount(KOS_PARAM_DFU_ALIAS, bleESN, bleKey);
#endif
    uint8_t blesn[20] = {0};
    memcpy(blesn, pData, len);
    ATE_MAIN_LOG("blesn:%s,%d", blesn, len);
    if (OSAL_NvWrite(SYS_OFFSET(eSN), pData, len) == SUCCESS)
    {
        if (OSAL_NvRead(SYS_OFFSET(eSN), blesn, len) == SUCCESS)
        {
            if (memcmp(pData, blesn, len) == 0)
            {
                memset(pAckDataBuf, 0, len);
                memcpy(pAckDataBuf, blesn, len); 
                *pAckDataLen = len;
                return CMD_EXE_OK;
            }
        }
    }
    return CMD_EXE_ERR;
}

/**
  * @brief  人脸测试
  *
  * @note
  */
static uint8_t ATE_FaceTest(uint8_t *pData)
{
    ATE_MAIN_LOG("ATE_FaceTest\r\n");
    if (*pData == 0x00)
    {
        SYS_CALL(Face_Set_Demo_Mode, 1);
        SYS_CALL(Face_Verity_Start);
        test_type = FACE_TEST;
    }
    else
    {
        test_type = 0xff;
    }
    return CMD_EXE_OK;
}

static uint8_t ATE_FacePvnTest(uint8_t *pData)
{
    ATE_MAIN_LOG("ATE_FacePvnTest\r\n");
    if(pData[0] ==  0)//人脸
    {
        if(pData[1] == 0)//打开人脸
        {
             SYS_CALL(Face_Set_Demo_Mode, 1);
            SYS_CALL(Face_Verity_Start);
            test_type = FACE_TEST;
        }
        else
        {
            test_type = 0xff;
        }
        newFaceReportFlag = 1; 
    }
    else if(pData[0] == 1)//掌静脉
    {
        if(pData[1] == 0)//打开掌静脉
        {
            PalmVein_Ctrl(PALMVEIN_CTRL_VERIFY,0,0);//启动掌静脉验证
            test_type = PVN_TEST;
        }
        else
        {
            test_type = 0xff;
        }
    }
    return CMD_EXE_OK;
}



/**
  * @brief  设定量产加密的秘钥
  *
  * @note
  */
static uint8_t ATE_Set_Face_Enc_Key(void)
{
    ATE_MAIN_LOG("ATE_Set_Face_Enc_Key\r\n");
    SYS_CALL(Face_Set_Enc_Key);
    test_type = FACE_TEST;
    return CMD_EXE_OK;
}

/**
  * @brief  读取人脸软件版本
  *
  * @param  pAckDataBuf：应答包数据域指针
  * @param  pAckDataLen：应答包长度
  * @return 命令执行结果
  */
static uint8_t ATE_ReadModeVersion(uint8_t *pdata, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    pAckDataBuf[0] = pdata[0];
    if (pdata[0] == 0x00)
    {
        ATE_MAIN_LOG("ATE_ReadFaceVersion\r\n");
        SYS_CALL(Face_Read_Version, &pAckDataBuf[1], (uint8_t *)pAckDataLen);
        *pAckDataLen = 16;
        return CMD_EXE_OK;
    }
    else if (pdata[0] == 0x02)
    {
        //读取讯美模块的SN,产测时用到
        ATE_MAIN_LOG("ATE_ReadXunMei Sn\r\n");
        ATE_RemoteXm_Send(TX_CMD_READ_XUNMEI_SN, NULL, 0, COMMAND);
        return CMD_EXECUTING;
    }
    // else if (pdata[0] == 0x04) //获取一大串版本信息
    // {
    //     ATE_MAIN_LOG("ATE_XmVersion\r\n");
    //     ATE_RemoteXm_Send(TX_CMD_XM_VERSION, NULL, 0, COMMAND);
    //     return CMD_EXECUTING;
    // }
    return CMD_EXE_ERR;
}

/**
 * @brief 读取NB的CSQ回调
 *
 *
 * @note
 */
static void FuncAte_NB_CSQ_Handle(uint8_t NbRssi)
{
    uint8_t ack_data[64] = {0};
    uint8_t CSQ = 0;
    uint8_t controlStatus = 0;

    ATE_MAIN_LOG("FuncAte_NB_CSQ_Handle NbRssi:%d\r\n",NbRssi);
    
    CSQ = NbRssi;
    ack_data[0] = 0x80;
    ack_data[1] = CSQ;
    ExtKds_Send(CMD_NB_CSQ, ack_data, 2, NULL); 

    controlStatus = NB_CONTROL_ENTER_PSM;
    Nb_SendCmdToNb(&controlStatus, sizeof(controlStatus));
}

/**
  * @brief  读取NB的CSQ
  *
  * @return 命令执行结果
  */
static uint8_t ATE_ReadNB_CSQ(void)
{
    ATE_MAIN_LOG("ATE_ReadNB_CSQ\r\n");
    SYS_CALL(NbMain_get_CSQ, FuncAte_NB_CSQ_Handle);

    return CMD_EXECUTING;
}

/**
  * @brief  智游者模块测试
  *
  * @param  pAckDataBuf：应答包数据域指针
  * @param  pAckDataLen：应答包长度
  * @return 命令执行结果
  */
static uint8_t ATE_PSensorTest(uint8_t *pdata)
{
    ATE_MAIN_LOG("ATE_PSensorTest\r\n");
    if (pdata[0] == 1) //开始
    {
        test_type = DOOR_SENSOR_TEST;
        SYS_CALL(Psensor_Calibration);
    }
    else
    {
        test_type = 0xff;
    }
    return CMD_EXE_OK;
}

/**
  * @brief  读取副板软件版本
  *
  */
// static uint8_t ATE_ReadOtherBoardVersion(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
// {
//     uint8_t version[8] = {0};
//     memset(version, 0, 8);

//     if(KOS_PARAM_DFU_ALIAS == DFU_DEVNUM_FRONT_MCU)
//     {
//         DFU_GetVersion(DFU_DEVNUM_REAR_MCU, version);
//     }
//     else
//     {
//         DFU_GetVersion(DFU_DEVNUM_FRONT_MCU, version);
//     }
//     ATE_MAIN_LOG("ATE_ReadOtherBoardVersion: %s\r\n", version);
//     memcpy(pAckDataBuf, version, 8);
//     *pAckDataLen = 8;
//     return CMD_EXE_OK;
// }

/**
  * @brief  读取凯迪仕wifi模块版本号
  * @note   
  * @param  *pAckDataBuf
  * @param  *pAckDataLen
  * @return uint8_t
  */
static uint8_t ATE_ReadKDSWifiVersion(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    uint8_t version[10] = {0};
    memset(version, 0, 10);

    DFU_GetVersion(DFU_DEVNUM_WIFI_MODULE, version);
    ATE_MAIN_LOG("ATE_ReadKDSWifiVersion: %s\r\n", version);
    memcpy(pAckDataBuf, version, 10);
    *pAckDataLen = 10;
    return CMD_EXE_OK;
}

/**
  * @brief  高速霍尔测试
  *
  */
static uint8_t ATE_HighSpeedHallTest(void)
{
    /* TODO */
    return CMD_EXE_OK;
}

#if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
/**
  * @brief  wifi信号强度测试
  * @note   
  * @param  *ssid
  * @param  len
  * @return uint8_t
  */
static uint8_t ATE_KDS_WifiRssiTest(uint8_t *ssid, uint16_t len)
{
    memset(wifi_ssid, 0x00, sizeof(wifi_ssid));
    memcpy(wifi_ssid, ssid, len);
    Wifi_Scan();
    return CMD_EXE_OK;
}

/**
  * @brief  设置服务器参数
  * @note   
  * @param  *pData 数据域
  * @param  *dataLen 数据域长度
  * @return uint8_t
  */
static uint8_t ATE_KDS_SetServerPara(uint8_t *pData, uint8_t dataLen)
{
#if ((defined DOMAIN_NAME_MAX) && (defined CAMERA_SUB_DEVICE))
    uint8_t read_temp[DOMAIN_NAME_MAX + 5] = {0};
    OSAL_NvWrite(SYS_OFFSET(mqtt_domain), pData, DOMAIN_NAME_MAX + 5);
    OSAL_NvRead(SYS_OFFSET(mqtt_domain), &read_temp, DOMAIN_NAME_MAX + 5);
    if (memcmp(read_temp, pData, DOMAIN_NAME_MAX + 5) == 0)
    {
        return CMD_EXE_OK;
    }
    return CMD_EXE_ERR;
#else
//    uint8_t read_temp[32] = {0};
//    OSAL_NvWrite(SYS_OFFSET(mqtt_domain), pData, 32);
//    OSAL_NvRead(SYS_OFFSET(mqtt_domain), &read_temp, 32);
//    if (memcmp(read_temp, pData, 32) == 0)
//    {
//        return CMD_EXE_OK;
//    }
    return CMD_EXE_ERR;
#endif
}

/**
  * @brief  读取服务器参数
  * @note   
  * @param  *pData 数据域
  * @param  *dataLen 数据域长度
  * @return uint8_t
  */
static uint8_t ATE_KDS_ReadServerPara(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
#if ((defined DOMAIN_NAME_MAX) && (defined CAMERA_SUB_DEVICE))
    *pAckDataLen = DOMAIN_NAME_MAX + 5;
    OSAL_NvRead(SYS_OFFSET(mqtt_domain), pAckDataBuf, DOMAIN_NAME_MAX + 5);
    return CMD_EXE_OK;
#else
//    *pAckDataLen = 35;
//    OSAL_NvRead(SYS_OFFSET(mqtt_domain), pAckDataBuf, 32);
    return CMD_EXE_OK;
#endif
}
#endif

#ifdef CAMERA_SUB_DEVICE
static uint8_t ATE_KDS_SetLogo(uint8_t *pData, uint8_t dataLen)
{
    uint8_t param[5] = {0};
    memcpy(param,pData,5);
    OSAL_NvWrite(SYS_OFFSET(disp_logo),param,5); 
    return CMD_EXE_OK;
}
#endif

/**
  * @brief  WIFI组件消息回调
  * @note   
  * @param  *msg
  * @param  len
  * @return void
  */
static void ATE_WifiMsgCb(void *msg, uint16_t len)
{
    uint8_t data[2] = {0x53, 0x01};
    WifiMsg_t *wifi = (WifiMsg_t *)msg;
    ATE_MAIN_LOG("recv wifi msg: %02x\r\n", wifi->msg_type);
    if (wifi->msg_type == WIFI_MSG_SCAN_REPLY)
    {
        for (int i = 0; i < wifi->ap_list.qty; i++)
        {
            if (strcmp(wifi_ssid, wifi->ap_list.ap[i].ssid) == 0)
            {
                data[1] = 0x00;
                break;
            }
        }
        ExtKds_Send(CMD_XM_PERIPHERAL_REPORT, &data, 2, extend_kds_send_callback); //上报
    } 
}


static void ATE_PvnMsgCb(void *msg, uint16_t len)
{
    uint8_t pvnStatu =0;
    PalmVeinMsg_t *pMsg = (PalmVeinMsg_t *)msg;
    if(test_type == PVN_TEST)
    {
        switch (pMsg->action)
        {
            case PALMVEIN_ACTION_VERIFY_OK: //验证成功
            case PALMVEIN_ACTION_VERIFY_ERR:
            pvnStatu =1;
            ATE_FacePvnReport(CMD_READ_FACE_REPORT,1,pvnStatu);
            break;
            case PALMVEIN_ACTION_NOPALMVEIN://未找到手掌
            pvnStatu =0;
            ATE_FacePvnReport(CMD_READ_FACE_REPORT,1,pvnStatu);
            break;
            case PALMVEIN_ACTION_ENC_SUCCESS: //加密成功
            Audio_Play(SHE_ZHI_CHENG_GONG, SET);
            pvnStatu =0;
            ATE_FacePvnReport(CMD_SET_FACE_ENC_KEY_REPORT,1,pvnStatu);
            break;
            case PALMVEIN_ACTION_ENC_FAIL: //加密失败
            Audio_Play(SHE_ZHI_SHI_BAI, SET);
            pvnStatu =1;
            ATE_FacePvnReport(CMD_SET_FACE_ENC_KEY_REPORT,1,pvnStatu);
            break;
            case PALMVEIN_ACTION_ENCRYPTED://系列已存在
            Audio_Play(SHE_ZHI_SHI_BAI, SET);
            pvnStatu =2;
            ATE_FacePvnReport(CMD_SET_FACE_ENC_KEY_REPORT,1,pvnStatu);
            break;
            default:break;
        }
    }
    
}

/**
  * @brief  显示屏测试
  *
  */
static uint8_t ATE_XM_IoTest(void)
{
    test_type = XM_IO_TEST;
    SYS_CALL(XunMei_SendWakeSignal);
    return CMD_EXECUTING;
}

/**
  * @brief  显示屏测试
  *
  */
static uint8_t ATE_LcdTest(uint8_t color)
{
    uint8_t test = color;
    #if defined(MENU_TYPE_OLD)
    ATE_MAIN_LOG("ATE_OledTest display :%d",color);
    if(test == 0)
    {
        Oled_PopUpDisplay(POPUPS_OLED_TEST_WHITE,POPUPS_NULL,POP_UP_WINDOW_TIME+18500);//弹框20s //屏幕全灭
    }
    else
    {
        Oled_PopUpDisplay(POPUPS_OLED_TEST_BLACK,POPUPS_NULL,POP_UP_WINDOW_TIME+18500);//弹框20s //屏幕全灭
    }
    return CMD_EXE_OK;
    #else

        #if BOARD_MHAH0_A
        Lcd_DisplayGif(BMP_RED,BMP_BLUE,PICTURE_CENTER,PICTURE_CENTER,500,200);
        return CMD_EXE_OK;
        #else


        #ifdef CAMERA_SUB_DEVICE
            //TODO 调用camera组件接口测试显示屏
        #else
            ATE_RemoteXm_Send(TX_CMD_XM_LCD_TEST, &test, sizeof(test), COMMAND);
        #endif  /* END FOR CAMERA_SUB_DEVICE */
        #endif

    return CMD_EXECUTING;
    #endif
    
}

/**
  * @brief  讯美搜索wifi rssi测试
  *
  */
static uint8_t ATE_XM_WifiRssiTest(uint8_t *rssi, uint16_t len)
{
    test_type = CMD_XM_WIFI_RSSI_TEST;
    xunmei_peripherals_cmd = CMD_XM_WIFI_RSSI_TEST;
    ATE_RemoteXm_Send(TX_CMD_XM_WIFI_TEST, rssi, len, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  讯美人脸OTA usb通信接口测试
  *
  */
static uint8_t ATE_XM_OtaRelatedTest(uint8_t param)
{
    uint8_t test = param;
    ATE_MAIN_LOG("ATE_XM_OtaRelatedTest:%02X \r\n", param);
    if (test == 1) //产测人脸usb
    {
        SYS_CALL(Face_OTA_Start);
    }
    else if (test == 0) //产测讯美usb
    {
        DFU_SetDevNum(0xAA, 0, 0, 0);
        DFU_JumpApp(KOS_PARAM_DFU_ALIAS, 0);
    }
    return CMD_EXE_OK;
}

/**
  * @brief  厂内固件升级（上位机通过前后板连接串口，模拟后板给前板发一个PUBLISH命令）
  * 
  * OTA前板
  * 命令：FF FF 55 B5 AF 11 00 04 11 01 00 00 00 00 00 00 00 00 00 5C 00 01 00 06
  * 应答：FF FF 55 4C D5 02 00 84 11
  * 
  * OTA语音
  * 命令：FF FF 55 36 A6 11 00 04 12 01 00 00 00 00 00 00 00 00 00 5C 00 01 00 08
  * 应答：FF FF 55 2F E5 02 00 84 12
  * 
  * OTA LCD模块的MCU
  * 命令：FF FF 55 8E CD 11 00 04 13 01 00 00 00 00 00 00 00 00 00 5C 00 01 00 15
  * 应答：FF FF 55 0E F5 02 00 84 13
  */
static void ATE_FirmwareUpdate(uint8_t devNum)
{
    ATE_MAIN_LOG("ATE Firmware update: %d\r\n", devNum);
    DFU_SetDevNum(devNum + KOS_DFU_DEVNUM_MAX, 0, 0, 0);
    DFU_JumpApp(KOS_PARAM_DFU_ALIAS, 0);
}

/**
  * @brief  讯美外设测试  mic 声音  红外补光灯
  * cmd 测试的命令
  */
static uint8_t ATE_XM_PeripheralsTest(uint8_t cmd, uint8_t data)
{
    ATE_MAIN_LOG("ATE_XM_PeripheralsTest:%02x, %02x \r\n", cmd, data);
    xunmei_peripherals_cmd = cmd;
    uint8_t param = 0;
    if (cmd == CMD_XM_MIC_TEST)
    {
        param = 0;
    }
    else if (cmd == CMD_XM_VOICE_TEST)
    {
        param = 3;
    }
    else if (cmd == CMD_XM_RED_LED_TEST)
    {
        if (data == 1)
        {
            param = 4;
            Led_Set("LED", LED_OFF, 0, 0); //键盘灯
        }
        else
            param = 5;
    }
    else if (cmd == CMD_XM_VIDEO_TEST)
    {
        param = 1;
    }
    else if (cmd == CMD_XM_PIR_TEST)
    {
        param = 2;
    }
    ATE_RemoteXm_Send(TX_CMD_XM_MODULE_TEST, &param, 1, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  讯美进入退出产测模式
  * param 测试的命令
  */
static uint8_t ATE_XM_InOutTestMode(uint8_t param)
{
    uint8_t mode = 0;
    if (param == 0)
        mode = 1;
    ATE_RemoteXm_Send(TX_CMD_XM_TEST_MODE, &mode, 1, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  配置讯美模组服务器参数
  * data 服务器参数
  */
static uint8_t ATE_XM_SetServerPara(uint8_t *data, uint8_t len)
{
    ATE_RemoteXm_Send(TX_CMD_XM_SET_SERVER_PARA, data, len, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  配置开机logo
  * data 参数
  */
static uint8_t ATE_XM_SetLogo(uint8_t *data, uint8_t len)
{
    ATE_RemoteXm_Send(TX_CMD_XM_SET_LOGO, data, len, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  读取讯美模组服务器参数
  * data 参数
  */
static uint8_t ATE_XM_ReadServerPara(uint8_t *data, uint8_t len)
{
    ATE_RemoteXm_Send(TX_CMD_XM_READ_SERVER_PARA, data, len, COMMAND);
    return CMD_EXECUTING;
}

/**
  * @brief  读取开机logo
  * data 参数
  */
static uint8_t ATE_XM_ReadLogo(uint8_t *data, uint8_t len)
{
    ATE_RemoteXm_Send(TX_CMD_XM_READ_LOGO, data, len, COMMAND);
    return CMD_EXECUTING;
}

#ifdef CAMERA_SUB_DEVICE
/**
  * @brief  读取开机logo
  * data 参数
  */
static uint8_t ATE_KDS_ReadLogo(uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    *pAckDataLen = 5;
    OSAL_NvRead(SYS_OFFSET(disp_logo),pAckDataBuf,5); 
    return CMD_EXE_OK;
}
#endif
//锁体测试
static uint8_t ATE_LockDaiTest(void)
{
//    Lock_dai_test = 0;
//    Lock_TestCtrl(HALL_OC_TEST_MODE, NULL, 0); 
    return CMD_EXE_OK;
}

//手动锁体测试
static uint8_t ATE_ManulLockDaiTest(void)
{
//    Lock_dai_test = 1;
//    Lock_TestCtrl(MANUAL_HALL_OC_TEST_MODE, NULL, 0); 
    return CMD_EXE_OK;
}
//外置电机测试
static uint8_t ATE_ExternMotoTest(uint8_t act)
{
    uint8_t mode =0;
    mode = (act == 0) ? 3: act;
    Lock_TestCtrl(MOTOR_TEST_MODE, &mode, 1); 
    return CMD_EXE_OK;
}
//OLED 测试
static uint8_t ATE_OledTest(uint8_t dis)
{
    ATE_MAIN_LOG("ATE_OledTest display :%d",dis);
    #if defined(MENU_TYPE_OLD)
    if(dis == 0)
    {
        Oled_PopUpDisplay(POPUPS_OLED_TEST_WHITE,POPUPS_NULL,POP_UP_WINDOW_TIME+18500);//弹框20s //屏幕全灭
    }
    else
    {
        Oled_PopUpDisplay(POPUPS_OLED_TEST_BLACK,POPUPS_NULL,POP_UP_WINDOW_TIME+18500);//弹框20s //屏幕全灭
    }
    #endif
    return CMD_EXE_OK;
}
/**
  * @brief  键盘灯闪烁测试
  *
  * @note   20ms执行一次
  */
static char breathLedTable[3][10] = {"LED_PWM_R", "LED_PWM_G", "LED_PWM_B"};
static uint8_t breathLedOrder = 0;
static void ATE_KeyBoardLedFlash(void)
{
    static uint8_t status = 0;
    static uint8_t count = 0;
    
    if (++count < 25)
    {
        return;
    }
    count = 0;

    if ((test_type == LED_TEST) && (led_test_status == LED_TEST_ALL)) //测试所有LED灯（有感应把手时，主控控制开关门指示灯）
    {
        status = !status;

        Led_Set("LED", (LedCtrlType_enum_t)status, 0, 0); //键盘灯
#if (defined(WFV01)||defined(WFV_F)||defined(DL5))
        static uint8_t count_ctrl = 0;
        if (count_ctrl == 1 && !status)
        {
            Led_Set("LED_#", LED_OFF, 0, 0); //键盘灯
            // Led_Set("LED_GREEN", LED_ON, 0, 0); //键盘灯
            Led_Set("LED_RED", LED_OFF, 0, 0); //键盘灯
            Led_Set("LED_GREEN", LED_FLASH, 1, 500);
        }
        else if (count_ctrl == 2 && !status)
        {
            Led_Set("LED_GREEN", LED_OFF, 0, 0); //键盘灯
            Led_Set("LED_RED", LED_ON, 0, 0); //键盘灯
        }
        else
        {
            Led_Set("LED_GREEN", LED_OFF, 0, 0); //键盘灯
            Led_Set("LED_RED", LED_OFF, 0, 0); //键盘灯
        }

        if (status)
        {
            count_ctrl++;
            if (count_ctrl == 3)
                count_ctrl = 0;
        }
#elif (defined(BOARD_MJAS0_A) || defined(BOARD_MJC50_A))
        static uint8_t count_ctrl = 0;
        if (count_ctrl == 1 && !status)
        {
            Led_Set("LED_OPEN", LED_ON, 0, 0);   //绿灯
            Led_Set("LED_CLOSE", LED_OFF, 0, 0); //红灯
            Led_Set("LED_BLUE", LED_OFF, 0, 0);  //蓝灯
        }
        else if (count_ctrl == 2 && !status)
        {
            Led_Set("LED_OPEN", LED_OFF, 0, 0);   //绿灯
            Led_Set("LED_CLOSE", LED_ON, 0, 0); //红灯
            Led_Set("LED_BLUE", LED_OFF, 0, 0);  //蓝灯
        }
        else
        {
            Led_Set("LED_OPEN", LED_OFF, 0, 0);   //绿灯
            Led_Set("LED_CLOSE", LED_OFF, 0, 0); //红灯
            Led_Set("LED_BLUE", LED_ON, 0, 0);  //蓝灯
        }
        if (status)
        {
            count_ctrl++;
            if (count_ctrl == 3)
                count_ctrl = 0;
        }
#elif defined(LKM32_MB_V1)
        static uint8_t count_ctrl = 0;
        if (count_ctrl == 1 && !status)
        {
            Led_Set("LED_LOGO_W", LED_ON, 0, 0);   //白灯
            Led_Set("LED_LOGO_R", LED_OFF, 0, 0);  //红灯
            Led_Set("LED_LOGO_B", LED_OFF, 0, 0);  //蓝灯
        }
        else if (count_ctrl == 2 && !status)
        {
            Led_Set("LED_LOGO_W", LED_OFF, 0, 0);  //白灯
            Led_Set("LED_LOGO_R", LED_ON, 0, 0);   //红灯
            Led_Set("LED_LOGO_B", LED_OFF, 0, 0);  //蓝灯
        }
        else
        {
            Led_Set("LED_LOGO_W", LED_OFF, 0, 0);   //白灯
            Led_Set("LED_LOGO_R", LED_OFF, 0, 0);   //红灯
            Led_Set("LED_LOGO_B", LED_ON, 0, 0);    //蓝灯
        }
        if (status)
        {
            count_ctrl++;
            if (count_ctrl == 3)
                count_ctrl = 0;
        }

        Led_Set("LED_BAT", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_LP", (LedCtrlType_enum_t)status, 0, 0);
#else
        Led_Set("LED_BAT", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_OPEN", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_CLOSE", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_RED", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_GREEN", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_LP", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_FS", (LedCtrlType_enum_t)status, 0, 0);
        Led_Set("LED_LOCK", (LedCtrlType_enum_t)status, 0, 0);
//        Finger_SetLed( status );                                    // 超声波指纹带有LED, 这里和其他LED一起闪烁

        Led_Set(breathLedTable[breathLedOrder], (LedCtrlType_enum_t)status, 0, 0);
#endif

        if (status)
        {
            breathLedOrder++;
            if (breathLedOrder == 3)
                breathLedOrder = 0;
        }
    }
}

static void Agingtest_led(uint8_t count)
{
    uint8_t count_tmp = count;
    switch (count_tmp)
    {
        case 1:
//            FuncLed_SetLedState(LED_STA_CLOSE_LOCK, NULL);
            break;
        case 2:
//            FuncLed_SetLedState(LED_STA_OPEN_LOCK, NULL);
            break;
        case 3:
//            FuncLed_SetLedState(LED_STA_WAKEUP, NULL);
            break;
        default:
        break;
    }
}
static void ATE_ProcessAging(void)
{
    static uint16_t count = 0;
    static uint8_t led_count = 0;
    uint8_t dataBuff[1] = {0};
    if (ATE_GetProductionTestMode() != TESTMODE_AGING)
    {
        count = 0;
        return;
    }

    if (count == 0)
    {
        OSAL_AppStateSet("APP_LOCAL", DISABLE);
        OSAL_AppStateSet("APP_BLE", DISABLE);
        OSAL_AppStateSet("APP_REMOTE", DISABLE);
        /* 建议同一个类型的app不要起那么多的名字，用通用的名字 */
        OSAL_AppStateSet("REMOTE_XM_LOCAL", DISABLE);
        OSAL_AppStateSet("APP_LOCAL_REV", DISABLE);
        OSAL_AppStateSet("BLE_LOCAL", DISABLE);
        OSAL_AppStateSet("REMOTE_APP", DISABLE);
        OSAL_AppStateSet("APP_LOCAL_PLUS", DISABLE);
        OSAL_AppStateSet("BLE_Main", DISABLE);
        
        OSAL_UpdateSleepTime(0XFFFFFFFF, 0); //老化模式下不休眠
    }
    else if (count == 250)
    {
//        FuncAudio_PlayAudio(AUDIO_STA_OPEN_LOCK, SET);
//        FuncLed_SetLedState(LED_STA_KEYBOARD_ON, NULL);
        if (led_count == 3)
            led_count = 0;
        led_count++;
        Agingtest_led(led_count);
        dataBuff[0] = LOCK_CTRL_UNLOCK;
        Lock_TestCtrl(LOCK_UNLOCK_TEST_MODE, dataBuff, 1);
    }
    else if (count == 750)
    {
//        FuncAudio_PlayAudio(AUDIO_STA_CLOSE_LOCK, SET);
//        FuncLed_SetLedState(LED_STA_ALL_OFF, NULL);
        dataBuff[0] = LOCK_CTRL_LOCKED;
        Lock_TestCtrl(LOCK_UNLOCK_TEST_MODE, dataBuff, 1);
    }
    if (++count > 1000)
    {
        count = 0;
    }
}

/**
  * @brief  锁贴项目电机老化处理函数
  *
  * @note   
  */
static void ATE_ProcessExtendMotorAging()
{
    static uint16_t count = 0;

    if (ATE_GetProductionTestMode() != TESTMODE_AGING)
    {
        count = 0;
        return;
    }

    if (count == 0)
    {
    }
    else if (count == 500)
    {
        Led_Set("LED_RED", LED_OFF, 0, 0);
        Led_Set("LED_GREEN", LED_ON, 0, 0);
//        Lock_Ctrl(LOCK_CTRL_UNLOCK);            //开锁
        
    }
    else if (count == 850)
    {
        Led_Set("LED_RED", LED_ON, 0, 0);
        Led_Set("LED_GREEN", LED_ON, 0, 0);
//        Lock_Ctrl(LOCK_CTRL_UNLOCK_BACK);
    }
    else if (count == 1200)
    {
        Led_Set("LED_RED", LED_ON, 0, 0);
        Led_Set("LED_GREEN", LED_OFF, 0, 0);
//        Lock_Ctrl(LOCK_CTRL_LOCKED);            //关锁
    }


    if (++count > 1260)
    {
        count = 0;
    }
}

static void ATE_test_process_cb(TimerHandle_stu_t handle)
{
    ATE_KeyBoardLedFlash();
    #ifdef DL5
    //外置电机老化处理
    ATE_ProcessExtendMotorAging();
    #else
    ATE_ProcessAging();
    #endif
}

TestMode_enum_t mode = TESTMODE_NORMAL;
static void ATE_SendProductCmd(TimerHandle_stu_t handle)
{
    printf("\r\n shanngdian\r\n");
    ATE_ReportStatus(0x01, mode); //上电上报
}

/**
  * @brief  产测模式初始化
  *
  * @note   进入测试模式关闭休眠功能；上电或唤醒上报状态
  */
static void ATE_Init(void)
{
    __EFRAM static bool powerOnFlag = true;
    TimerHandle_stu_t AteTimer = NULL;
    mode = ATE_GetProductionTestMode();
    ATE_MAIN_LOG("ATE_Init mode:%02X\r\n", mode);
    if (mode == TESTMODE_AGING)
    {
        //直接进入老化模式
        ATE_SetProductionTestMode(TESTMODE_AGING);

        OSAL_UpdateSleepTime(0XFFFFFFFF, 0); //老化模式下不休眠

        AteTimer = OSAL_TimerCreate(ATE_test_process_cb, ATE_AGING_TIMER, SET);
        OSAL_TimerSet(AteTimer, TIM_RUN_ONLY_WAKE); //设置定时器仅唤醒状态工作
    }
    else
    {
        OSAL_UpdateSleepTime(10000, 1);
    }

    if (powerOnFlag != false)
    {
        powerOnFlag = false;
        AteTimer = OSAL_TimerCreate(ATE_test_process_cb, ATE_AGING_TIMER, SET);
        OSAL_TimerSet(AteTimer, TIM_RUN_ONLY_WAKE); //设置定时器仅唤醒状态工作

        OSAL_TimerCreate(ATE_SendProductCmd, 1300, RESET);//< 这个定时器太小会出现不接感应把手只插USB无法进入产测
    }
    else
    {
        if (mode == TESTMODE_TESTING) //测试模式下才有 唤醒上报
        {
            ATE_ReportStatus(0x02, mode); //唤醒上报
        }
    }
}

static void extend_kds_send_callback(uint8_t cmd, void *data, uint16_t len)
{
}

/**
  * @brief  BUTTON组件上报按键值
  * @note   
  *
  * @param  pdata 待传入的按键值
  * @return void
  */
static void ATE_ButtonReport(uint8_t *pdata)
{
    ExtKds_Send(CMD_READ_KEY_REPORT, pdata, 4, extend_kds_send_callback); //上报
}

/**
  * @brief  距离传感器上报校准状态
  * @note   
  *
  * @param  pdata 待传入的按键值
  * @return void
  */
static void ATE_DistanceCalReport(uint8_t result)
{
    uint8_t statusBuffer = result ? 0 : 1;
    ATE_MAIN_LOG("ATE_DistanceCalReport result:%02X\r\n", result);
    ExtKds_Send(CMD_TOF_CAL_RESULT_REPORT, &statusBuffer, 1, extend_kds_send_callback); //上报
}

/**
  * @brief  TOUCH组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void ATE_TouchMsgCb(void *msg, uint16_t len)
{
    TouchMsg_t *touch = (TouchMsg_t *)msg;
    uint8_t dataBuf[4] = {0XFF, 0XFF, 0XFF, 0XFF};
    char led[16] = "LED";
    ATE_MAIN_LOG("ATE_TouchMsgCb\r\n");
    if (test_type == KEY_TEST)
    {
        if (touch->action == USER_ACTION_RELEASE)
        {
            Led_Set(led, LED_ON, 0, 0);
            Led_Set("LED_LOCK", LED_ON, 0, 0);            
        }
        else if (touch->action == USER_ACTION_PRESS)
        {
            led[3] = touch->keyNum;
            if (touch->keyNum == 'L')
                strcpy( led, "LED_LOCK" );
            Led_Set(led, LED_OFF, 0, 0);
//            Audio_Play(AN_JIAN_YIN_DI, SET);
            Beep_Set(1, 50);
            dataBuf[0] = touch->keyNum;
            ATE_ButtonReport(dataBuf);
            if (touch->keyNum == 'D')
            {
//                Audio_PlayDoorbell(HUAN_YING_YIN, 2); //< 后板播放门铃
                SYS_CALL(Remote_DoorBellNotify);  //< 讯美播放门铃
            }
        }   
    }
}

/**
  * @brief  处理卡片消息
  * @note
  *
  * @param  card_id:卡片ID
  * @param  card_len：卡片ID长度
  */
static void ATE_CardMsgCb(void *msg, uint16_t len)
{
    CardMsg_t *card = (CardMsg_t *)msg;
    ATE_MAIN_LOG("ATE_CardMsgCb: cardLen: %02x\r\n", card->cardLen);
    if (test_type == CARD_TEST)
    {
        if (card->cardLen != 0)
        {
            uint8_t cardData[11] = {0};
            Audio_Play(ZHI_WEN_YIN_DO, SET);                              //播放刷卡提示音
            cardData[0] = ((card->cardLen & 0XC0) == 0X80) ? 0x81 : 0x80; //卡合法: 0x80 非法: 0x81
            memcpy(&cardData[1], card->cardId, 10);
            ExtKds_Send(CMD_READ_CARD_REPORT, cardData, 11, extend_kds_send_callback); //上报
        }
    }
}

/**
  * @brief  tof测试
  *
  * @note
  */
static uint8_t ATE_DistanceTest(uint8_t *pData)
{
    ATE_MAIN_LOG("ATE_DistanceTest\r\n");
    if (*pData == 0x00)
    {
        test_type = DISTANCE_TEST;
        #ifdef LOCK_TDKSENSOR_DEVICE
        SYS_CALL(dsensor_set_demo_mode, 1);
        #endif
        SYS_CALL(dsensor_power_ctrl, ENABLE);
    }
    else
    {
        test_type = 0xff;
        #ifdef LOCK_TDKSENSOR_DEVICE
        SYS_CALL(dsensor_set_demo_mode, 0);
        SYS_CALL(dsensor_power_ctrl, DISABLE);
        #endif
    }
    return CMD_EXE_OK;
}

/**
  * @brief  tof校准
  *
  * @note
  */
static uint8_t ATE_DistanceCal(void)
{
    ATE_MAIN_LOG("ATE_DistanceCal\r\n");
    return CMD_EXE_OK;
}

/**
  * @brief  处理指纹消息
  * @note
  *
  * @param  msg:指纹消息
  * @param  len： 指纹消息长度
  */
static void ATE_FingerMsgCb(void *msg, uint16_t len)
{
    FingerMsg_t *finger = (FingerMsg_t *)msg;
    ATE_MAIN_LOG("ATE_FingerMsgCb: action=%d\r\n", finger->action);
    if (test_type == FPT_TEST)
    {
        if (finger->action == FINGER_ACTION_GET_IMAGE_OK)
        {
            Audio_Play(ZHI_WEN_YIN_DO, SET);
            uint8_t fptData = 100;
            ExtKds_Send(CMD_READ_FPT_REPORT, &fptData, 1, extend_kds_send_callback); //上报
        }
    }
}

/**
  * @brief  处理指静脉消息
  * @note
  *
  * @param  msg:指静脉消息
  * @param  len： 指静脉消息长度
  */
static void ATE_FingerveinMsgCb(void *msg, uint16_t len)
{
    FingerveinMsg_t *fingervein = (FingerveinMsg_t *)msg;
    ATE_MAIN_LOG("ATE_FingerveinMsgCb\r\n");
    if (test_type == FVN_TEST)
    {
        if (fingervein->action == FINGERVEIN_ACTION_ATE_TEST_RESULT)
        {
            if (fingervein->fingerveinNumber != 0x11)           //0x11表示未放入手指，不应该播报“嘟”
            {
                Audio_Play(ZHI_WEN_YIN_DO, SET);
            }
            uint8_t fvnData = fingervein->fingerveinNumber;
            ExtKds_Send(CMD_READ_FVN_REPORT, &fvnData, 1, extend_kds_send_callback); //上报
        }
    }
}

/**
  * @brief  上报人脸状态
  * @note
  *
  * @parm   cmd:上报命令字
  * @param  statu:状态
  */
static void ATE_FaceReport(uint8_t cmd, uint8_t statu)
{
    ExtKds_Send(cmd, &statu, 1, extend_kds_send_callback); //上报
}



/**
  * @brief  人脸/掌静脉 状态上报
  * @note
  *
  * @parm   cmd:上报命令字
  * @param  statu:状态
  * @param  type: 0 人脸  1掌静脉
  */

static void ATE_FacePvnReport(uint8_t cmd ,uint8_t type ,uint8_t statu)
{
    uint8_t tData[2]={0};
    tData[0] = type;
    tData[1] = statu;
    ExtKds_Send(cmd, tData, 2, extend_kds_send_callback); //上报
}


/**
  * @brief  处理人脸消息
  * @note
  *
  * @param  msg:人脸消息
  * @param  len： 人脸消息长度
  */
static void ATE_FaceMsgCb(void *msg, uint16_t len)
{
    FaceMsg_t *pMsg = (FaceMsg_t *)msg;
    uint8_t face_status = 1;
    if (test_type == FACE_TEST)
    {
        ATE_MAIN_LOG("ATE_FingerMsgCb pMsg->action:%d\r\n", pMsg->action);
        switch (pMsg->action)
        {
        case FACE_ACTION_VERIFY_OK:
            Audio_Play(ZHI_WEN_YIN_DO, SET);
            face_status = 1;
            if(newFaceReportFlag)
            {
                ATE_FacePvnReport(CMD_READ_FACE_REPORT,0, face_status);
            }
            else
            {
                ATE_FaceReport(CMD_READ_FACE_REPORT, face_status);
            }
            break;
        case FACE_ACTION_NOFACE:
            Audio_Play(ZHI_WEN_YIN_DO, SET);
            face_status = 0;
            if(newFaceReportFlag)
            {
                ATE_FacePvnReport(CMD_READ_FACE_REPORT,0, face_status);
            }
            else
            {
                ATE_FaceReport(CMD_READ_FACE_REPORT, face_status);
            }
            break;
        case FACE_ACTION_ENC_SUCCESS:
            Audio_Play(SHE_ZHI_CHENG_GONG, SET);
            face_status = 0;
            if(newFaceReportFlag)
            {
                ATE_FacePvnReport(CMD_SET_FACE_ENC_KEY_REPORT,0, face_status);
            }
            else
            {
                ATE_FaceReport(CMD_SET_FACE_ENC_KEY_REPORT, face_status);
            }
            break;
        case FACE_ACTION_ENCRYPTED:
            Audio_Play(SHE_ZHI_CHENG_GONG, SET);
            face_status = 0;
            if(newFaceReportFlag)
            {
                ATE_FacePvnReport(CMD_SET_FACE_ENC_KEY_REPORT,0, face_status);
            }
            else
            {
                ATE_FaceReport(CMD_SET_FACE_ENC_KEY_REPORT, face_status);
            }
            break;
        case FACE_ACTION_ENC_FAIL:
            Audio_Play(SHE_ZHI_CHENG_GONG, SET);
            face_status = 1;
            if(newFaceReportFlag)
            {
                ATE_FacePvnReport(CMD_SET_FACE_ENC_KEY_REPORT,0, face_status);
            }
            else
            {
                ATE_FaceReport(CMD_SET_FACE_ENC_KEY_REPORT, face_status);
            }
            break;
        default:
            break;
        }
    }
    switch (pMsg->action)
    {
    case FACE_ACTION_ENTER_OTA_MODE: //进入打开usb模式
    {
        uint8_t test = 1;
        ATE_MAIN_LOG("FACE_ACTION_ENTER_OTA_MODE\r\n");
        ATE_RemoteXm_Send(TX_CMD_XM_FACE_USB_TEST, &test, 1, COMMAND);
    }
    break;
    default:
        break;
    }
}

/**
  * @brief  处理消息
  * @note
  *
  * @param  msg:人脸DSensor传感器消息
  * @param  len： 人脸消息长度
  */
static void ATE_DSensorMsgCb(void *msg, uint16_t len)
{
    static uint32_t last_timestamp = 0;
    DsensorMsg_t *pMsg = (DsensorMsg_t *)msg;
    if (test_type == DISTANCE_TEST)
    {
        if (OSAL_GetTickCount() - last_timestamp < 500)
        {
            return;
        }
        last_timestamp = OSAL_GetTickCount();
        if (pMsg->type == READ_DISTANCE)
        {
            uint8_t data[2] = {0};
            if (pMsg->ps_msg.distance == 0)
            {
                data[0] = 0XFF;
            }
            else
            {
                data[0] = pMsg->ps_msg.distance / 10;
                data[1] = pMsg->ps_msg.cfi;
            }
            ExtKds_Send(CMD_READ_DISTANCE_REPORT, data, 2, extend_kds_send_callback); //上报
            ATE_MAIN_LOG("ATE_DSensorMsgCb distance:%d, cfi: %d\r\n", data[0], data[1]);
        }
        else if(pMsg->type == WANDER_TRIG)
        {
            uint8_t data[2] = {0x57, 0x00};
            if (pMsg->wander_msg.alarm == 1)
            {
                ATE_MAIN_LOG("HOVER ALARM");
                ExtKds_Send(CMD_XM_PERIPHERAL_REPORT, &data, 2, extend_kds_send_callback); //上报
            }
        }
    }

    if (pMsg->type == CAL_RESULT)
    {
        ATE_DistanceCalReport(pMsg->cal_msg.result);
    }
}

/**
  * @brief  获取讯美模块的SN回调0X09
  * @note         
  * @param res:ACK结果
  * @param in:ACK数据
  * @param len:ACK数据长度 
  *
  * @return 
  */
static void ATE_RemoteXm_GetModleSn_Cb(uart_send_res_enum_t res, uint8_t *in, uint16_t len)
{
    uint8_t ack_data[64] = {0};
    ATE_MAIN_LOG("RemoteXm_GetModleSn_Cb res :%02x\r\n", res);
    if (res == UART_SEND_SUCCEED)
    {
        ack_data[0] = 0x80;
        ack_data[1] = 0x02;
        memcpy(&ack_data[2], in, len);
        ExtKds_Send(CMD_TEST_READ_MODE_VERSION, ack_data, 34, NULL); //回复产测读SN命令
    }
    else
    {
        ack_data[0] = 0x81;
        ack_data[1] = 0x02;
        ExtKds_Send(CMD_TEST_READ_MODE_VERSION, ack_data, 2, NULL); //回复产测读SN命令
    }
}

/**
  * @brief  获取讯美模块的SN回调0X34
  * @note         
  * @param res:ACK结果
  * @param in:ACK数据
  * @param len:ACK数据长度 
  *
  * @return 
  */
static void ATE_RemoteXm_GetVersion_Cb(uart_send_res_enum_t res, uint8_t *in, uint16_t len)
{
    ATE_MAIN_LOG("ATE_RemoteXm_GetVersion_Cb res :%02x\r\n", res);
    if (res == UART_SEND_SUCCEED)
    {
        for (int i = 0; i < len; i++)
        {
            if (in[i] >= ' ' && in[i] <= '~')
            {
                xmVersions[i] = in[i];
            }
            else
            {
                xmVersions[i] = 0;
            }
        }
    }
}

/**
  * @brief  获取讯美模块的WIFI MAC回调0x44
  * @note         
  * @param res:ACK结果
  * @param in:ACK数据
  * @param len:ACK数据长度 
  *
  * @return 
  */
static void ATE_RemoteXm_GetWiFiMAC_Cb(uart_send_res_enum_t res, uint8_t *in, uint16_t len)
{
    uint8_t ack_data[64] = {0};
    ATE_MAIN_LOG("ATE_RemoteXm_GetWiFiMAC_Cb res :%02x\r\n", res);
    if (res == UART_SEND_SUCCEED)
    {
        ack_data[0] = 0x80;
        memcpy(&ack_data[1], in, len);
        ExtKds_Send(CMD_XM_READ_WIFI_MAC, ack_data, (len+1), NULL); //回复产测读wifi MAC命令
    }
    else
    {
        ack_data[0] = 0x81;
        ExtKds_Send(CMD_XM_READ_WIFI_MAC, ack_data, 1, NULL); //回复产测读wifi MAC命令
    }
}

/**
  * @brief  讯美人脸OTA usb通信接口测试
  * @note         
  * @param res:ACK结果
  * @param in:ACK数据
  * @param len:ACK数据长度 
  *
  * @return 
  */
static void ATE_RemoteXm_FaceUsbTest_Report(uart_send_res_enum_t res)
{
    ATE_MAIN_LOG("ATE_RemoteXm_FaceUsbTest_Report res :%02x\r\n", res);
    uint8_t ack_data = (res == UART_SEND_SUCCEED) ? 0x80 : 0x81;
    ExtKds_Send(CMD_TEST_USB_REPORT, &ack_data, 1, extend_kds_send_callback);
}

/**
  * @brief  讯美应答回调
  * @note   应答无数据域处理
  * @param res: ACK结果
  * @param in: ACK数据
  * @param len: ACK数据长度
  * @param kds_cmd: 要转发的kds命令
  *
  * @return 
  */
static void ATE_RemoteXm_ForwardAckMsg_Cb(uart_send_res_enum_t res, uint8_t *in, uint16_t len, uint8_t kds_cmd)
{
    uint8_t ack_data[128] = {0};
    ATE_MAIN_LOG("ATE_RemoteXm_ForwardAckMsg_Cb res :%02x, kds_cmd : %02x\r\n", res, kds_cmd);
    ack_data[0] = (res == UART_SEND_SUCCEED) ? 0x80 : 0x81;
    memcpy(&ack_data[1], in, len);
    ExtKds_Send(kds_cmd, &ack_data, len + 1, NULL);
}

/**
  * @brief 发送回调
  * @note   
  * @param res:ACK结果
  * @param cmd:命令
  * @param in_data:ACK数据
  * @param in_len:ACK数据长度
  * @return 
  */
static void ATE_RemoteXm_SendCallback(uart_send_res_enum_t res, uint8_t cmd, uint8_t *in_data, uint16_t in_len)
{
    ATE_MAIN_LOG("ATE_RemoteXm_SendCallback :%02X\r\n", cmd);
    switch (cmd)
    {
    case TX_CMD_READ_XUNMEI_SN: //获取模块SN（产测）
        ATE_RemoteXm_GetModleSn_Cb(res, in_data, in_len);
        break;
    case TX_CMD_XM_VERSION: //获取讯美所有MCU版本
        ATE_RemoteXm_GetVersion_Cb(res, in_data, in_len);
        break;
    case TX_CMD_XM_LCD_TEST: //测试讯美LCD
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_OLED_TEST);
        break;
    case TX_CMD_XM_WIFI_TEST: //讯美WIFI测试
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_XM_WIFI_RSSI_TEST);
        break;
    case TX_CMD_XM_MODULE_TEST: //讯美模组  讯美外设测试  mic 声音  红外补光灯
         ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, xunmei_peripherals_cmd);
        break;
    case TX_CMD_XM_TEST_MODE: //讯美模组进入退出产测模式
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_XM_IN_OUT_TEST_MODE);
        break;
    case TX_CMD_XM_SET_SERVER_PARA: //配置服务器参数
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_SET_SERVER_PARA);
        break;
    case TX_CMD_XM_SET_LOGO: //配置开机logo
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_SET_LOGO);
        break;
    case TX_CMD_XM_READ_SERVER_PARA: //读取服务器参数
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_READ_SERVER_PARA);
        break;
    case TX_CMD_XM_READ_LOGO: //读取开机logo
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_READ_LOGO);
        break;
    case TX_CMD_XM_READ_MAC: //读取wifi MAC地址
        ATE_RemoteXm_GetWiFiMAC_Cb(res, in_data, in_len);
        break;
    case TX_CMD_LANG_SET:       // 设置讯美的语言
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_XM_SET_LANGUAGE);
        Audio_SetLanguage( xm_language );
        break;        
    case TX_CMD_XM_SET_BOOT_ADDR: //配置根证书地址
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_WR_SERVICE_INFO);
        break;
    case TX_CMD_XM_READ_BOOT_ADDR: //读取根证书地址
        ATE_RemoteXm_ForwardAckMsg_Cb(res, in_data, in_len, CMD_WR_SERVICE_INFO);
        break;
    default:
        break;
    }
}

/**
  * @brief 命令发送
  * @note   
  * @param cmd:命令
  * @param pdata:发送的数据
  * @param len:数据长度
  * @param pack_type：命令类型
  * @return 
  */
static void ATE_RemoteXm_Send(uint8_t cmd, uint8_t *pdata, uint16_t len, cmd_packet_type pack_type)
{
    ATE_MAIN_LOG("RemoteXm_Send :%02X, pack_type:%02X\r\n", cmd, pack_type);
    SYS_CALL(XunmeiSend_Cmd, cmd, pdata, len, ATE_RemoteXm_SendCallback, pack_type);
}

/**
  * @brief  使模块进入低功耗模式0X10
  * @note   
  * @return 
  */
static void ATE_RemoteXm_SetLowPower(void)
{
    ATE_RemoteXm_Send(TX_CMD_LOWPOWER_MODE, NULL, 0, COMMAND);
    ATE_MAIN_LOG("ATE_RemoteXm_SetLowPower\r\n");
}

/**
  * @brief  设置讯美模块的语言 ( 锁也更正变化 )
  * @note   
  * @return 
  */
static uint8_t ATE_RemoteXm_SetLanguage(uint8_t language)
{
    xm_language = language;
    ATE_RemoteXm_Send(TX_CMD_LANG_SET, &language, 1, COMMAND);
    ATE_MAIN_LOG("ATE_RemoteXm_SetLanguage : %d\r\n", language);
    return CMD_EXECUTING;
}

/**
  * @brief  唤醒通知0X20命令处理，用于产测测试中断IO
  * @note   
  * @return 命令执行结果
  */
static uint8_t ATE_XUNMEI_IO_TEST(void)
{
    if (test_type == XM_IO_TEST)
    {
        uint8_t ack_data = 0x80;
        ExtKds_Send(CMD_TEST_INT_IO, &ack_data, 1, NULL); //回复ACK
        test_type = 0xff;
    }
    return 1;
}

/**
  * @brief  讯美按键上报
  * @note   data 按键值
  * @return 命令执行结果
  */
static uint8_t ATE_XUNMEI_ButtonReport(uint8_t data)
{
    if (test_type == KEY_TEST)
    {
        uint8_t key[4] = {0XFF, 0XFF, 0XFF, 0XFF};
        if (data == 0x10)
        {
            key[2] = 0X0B;
            ATE_ButtonReport(key);
        }
    }
    return 1;
}

/**
  * @brief  讯美主动上报消息 作为产测的ACK
  * @note
  *
  * @param  msg:讯美指令
  * @param  len： 讯美消息长度
  */
static void ATE_XUNMEI_PeripheralReport(uint8_t cmd, uint8_t result)
{
    uint8_t data[2] = {xunmei_peripherals_cmd, 0};
    data[1] = (result == 1) ? 0x00 : 0x01;
    ExtKds_Send(CMD_XM_PERIPHERAL_REPORT, &data, 2, extend_kds_send_callback); //上报
}





/**
  * @brief  订阅讯美消息
  * @note
  *
  * @param  msg:讯美指令
  * @param  len： 讯美消息长度
  */
static void ATE_XunmeiMsgCb(void *msg, uint16_t len)
{
    XunMeiMsg_t *xunmei_data = (XunMeiMsg_t *)msg;
    if (xunmei_data->msgType == XM_RECV_CMD_PACKET)
    {
        uint8_t res = XUNMEI_EXE_OK;
        ATE_MAIN_LOG("xunmei_data->cmd :%02X\r\n", xunmei_data->cmd);
        if (xunmei_data->cmd != TX_RX_CMD_WAKE_NOTIFI) //唤醒通知不用回ACK
        {
            SYS_CALL(XunmeiSend_Cmd, xunmei_data->cmd, &res, sizeof(res), NULL, COMMAND_ACK);
        }
        switch (xunmei_data->cmd)
        {
        case TX_RX_CMD_WAKE_NOTIFI:
            ATE_XUNMEI_IO_TEST();
            break; //唤醒通知
        case CMD_XM_BUTTON_REPORT:
            ATE_XUNMEI_ButtonReport(xunmei_data->data[0]);
            break; //上报讯美按键
        case TX_CMD_XM_WIFI_SCAN_REPORT:
        case TX_CMD_XM_VEDIO_TEST_REPORT:
        case TX_CMD_XM_PIR_TEST_REPORT:
            ATE_XUNMEI_PeripheralReport(xunmei_data->cmd, xunmei_data->data[0]);
            break;
        case TX_CMD_XM_ALL_DEV_REPORT:
            ATE_XUNMEI_PeripheralReport(xunmei_data->cmd, xunmei_data->data[1]);
            break;
        case TX_CMD_XM_USB_TEST_REPORT:
            ATE_RemoteXm_FaceUsbTest_Report((uart_send_res_enum_t)xunmei_data->data[0]);
            break;
        default:
            break;
        }
    }
    else if (xunmei_data->msgType == XM_EXEC_CB)
    {
        ATE_MAIN_LOG("cb: %x, res: %02x, cmd: %02x, len: %02x\r\n", xunmei_data->cb, xunmei_data->res, xunmei_data->cmd, xunmei_data->len);
        if (xunmei_data->cb)
        {
            xunmei_data->cb(xunmei_data->res, xunmei_data->cmd, xunmei_data->data, xunmei_data->len);
        }
    }
}

/**
  * @brief  PSENSOR组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void ATE_LockPsensorMsgCb(void *msg, uint16_t len)
{
    if (test_type == DOOR_SENSOR_TEST)
    {
        PsensorMsg_t *psensor = (PsensorMsg_t *)msg;
        uint8_t data = 0;
        ATE_MAIN_LOG("ATE_LockPsensorMsgCb,%d\r\n", psensor->msg);
        if (psensor->msg == PSENSOR_OPENED) //
        {
            ATE_MAIN_LOG("door is open\r\n");
            data = 0x10;
        }
        else if (psensor->msg == PSENSOR_CLOSED)
        {
            ATE_MAIN_LOG("door is close\r\n");
            data = 0x11;
        }
        else if (psensor->msg == PSENSOR_CAL_FAILED)
        {
            ATE_MAIN_LOG("calibration failed\r\n");
            data = 0x12;
        }
        else if (psensor->msg == PSENSOR_CAL_FINISHED)
        {
            ATE_MAIN_LOG("calibration is finished\r\n");
            data = 0x13;
        }
        ExtKds_Send(CMD_PSENSOR_REPORT, &data, 1, extend_kds_send_callback); //上报
    }
}

/**
  * @brief  读取门锁记录
  *
  * @param  pCmdDataBuf：命令包数据域指针
  * @param  pAckDataBuf：应答包数据域指针
  * @param  pAckDataLen：应答包长度
  * @return 命令执行结果， CMD_EXE_ONCE：命令执行成功还需再次执行， CMD_EXE_OK_END：命令执行结束
  */
static uint8_t ATE_ReadRecords(uint8_t *pCmdDataBuf, uint8_t *pAckDataBuf, uint16_t *pAckDataLen)
{
    static uint16_t times = 0;
    uint8_t type; //读取的类型
    uint16_t readStartNumber = 0, readEndNumber = 0;
    Ack_Records_stu_t *pAckData = (Ack_Records_stu_t *)pAckDataBuf;

    type = pCmdDataBuf[0];

    readStartNumber = pCmdDataBuf[1] | (pCmdDataBuf[2] << 8);
    readEndNumber = pCmdDataBuf[3] | (pCmdDataBuf[4] << 8);
    ATE_MAIN_LOG("read record %d, %d - %d\r\n", pCmdDataBuf[0], readStartNumber, readEndNumber);
    if (readStartNumber > readEndNumber)
    {
        return CMD_EXE_ERR;
    }

    pAckData->type = type;
    pAckData->number = SYS_CALL(Record_GetQty, 0, RECORD_MAX_QTY, type); //包个数（记录个数）
    pAckData->sn = readStartNumber + times;                              //包编号
    if (SYS_CALL(Record_GetQty, readStartNumber, readEndNumber, type) - times > 0)
    {
        SYS_CALL(Record_Read, (EventRecord_stu_t *)&pAckData->record, readStartNumber + times, type);
        times++;
        *pAckDataLen = sizeof(Ack_Records_stu_t);
        return CMD_EXE_ONCE;
    }
    else
    {
        times = 0;
        *pAckDataLen = sizeof(Ack_Records_stu_t);
        return CMD_EXE_OK_END;
    }
}


/**
  * @brief  LOCK组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void ATE_LockMsgCb(void *msg, uint16_t len)
{
    if (test_type == KEY_TEST) //当前处于按键测试
    {
//        LockSensorAction_t *button = (LockSensorAction_t *)msg;

//        ATE_LOG_D("button:%s, action:%d", button->name,button->action);
        uint8_t dataBuf[4] = {0XFF, 0XFF, 0XFF, 0XFF}; 
        uint8_t isKeyPressed = 0;
        
//		if (strcmp(button->name, "IR_LOCKED") == 0) //外贸锁光藕1
//        {
//            if (button->action == USER_ACTION_PRESS)
//            {
//                dataBuf[1] = 0x0E;
//                isKeyPressed = 1;
//            }
//        }
//        else if (strcmp(button->name, "IR_UNLOCK") == 0) //外贸锁光藕2
//        {
//            if (button->action == USER_ACTION_PRESS)
//            {
//                dataBuf[1] = 0x0F;
//                isKeyPressed = 1;
//            }
//        }
//        else if (strcmp(button->name, "HALL_CENTER") == 0) //外贸锁霍尔1
//        {
//            if (button->action == USER_ACTION_PRESS)
//            {
//                dataBuf[1] = 0x10;
//                isKeyPressed = 1;
//            }
//        }
//        else if (strcmp(button->name, "HALL_LEFT") == 0) //外贸锁霍尔2
//        {
//            if (button->action == USER_ACTION_PRESS)
//            {
//                dataBuf[1] = 0x11;
//                isKeyPressed = 1;
//            }
//        }     
//        else if (strcmp(button->name, "HALL_RIGHT") == 0) //外贸锁霍尔3
//        {
//            if (button->action == USER_ACTION_PRESS)
//            {
//                dataBuf[1] = 0x14;
//                isKeyPressed = 1;
//            }
//        }         
        if (isKeyPressed && test_type == KEY_TEST)
        {
            ATE_ButtonReport(dataBuf);
            Beep_Set(1, 100);
        }
    }
    else if(test_type == LED_TEST) //
    {
        return;
    }
    else
    {
        uint8_t dataBuff[4] = {0};
        uint8_t report_flag = 0;
        uint8_t isKeyPressed = 0;
        LockMsg_t *lock = (LockMsg_t *)msg;

        ATE_MAIN_LOG("ATE_LockMsgCb, door_status:%d, lock_status:%d", lock->door, lock->lock);//  ATE_LOG_D

        if (lock->door == USER_ACTION_RELEASE) //开门回拖
        {
            dataBuff[3] = 0x00;
            isKeyPressed = 1;
        }
        else if (lock->door == USER_ACTION_PRESS)
        {
            dataBuff[3] = 0x01;
            isKeyPressed = 1;
        }
        if (lock->lock == LOCK_ACTION_LOCKED || lock->lock == LOCK_ACTION_LOCKED_MACH) //上锁成功
        {
            report_flag = 1;
            dataBuff[0] = CMD_EXE_OK;
            dataBuff[2] = 0x00;
        }
//        else if (lock->lock == LOCK_ACTION_UNLOCK_NO_BACK || lock->lock == LOCK_ACTION_UNLOCK || lock->lock == LOCK_ACTION_AUTO_DIR_CHECK_SUCCESS) //开锁成功（开锁流程已结束，未回拖） 
//        {
//            report_flag = 1;
//            dataBuff[0] = CMD_EXE_OK;
//            dataBuff[2] = 0x00;
//        }
//        else if (lock->lock == LOCK_ACTION_DCI_ERROR || lock->lock == LOCK_ACTION_ABNORMAL || lock->lock == LOCK_ACTION_AUTO_DIR_CHECK_FAILED) 
//        {
//            report_flag = 1;
//            dataBuff[0] = CMD_EXE_ERR;
//            dataBuff[2] = (test_type == UNLOCK_TEST) ? 0x01 : 0x02;
//        }
//        else if (!((lock->sensorTestStatus[0] == 0) && (lock->sensorTestStatus[1] == 0))) //档片测试
//        {
//            report_flag = 1;
//            if(lock->sensorTestStatus[1] == 0)
//            {
//                dataBuff[0] = CMD_EXE_OK;
//            }
//            else
//            {
//                dataBuff[0] = CMD_EXE_ERR;
//            }
//        }

        if (report_flag)
        {
            if(test_type == UNLOCK_TEST || test_type == LOCKED_TEST)
            {
                dataBuff[1] = (test_type == UNLOCK_TEST) ? 0x00 : 0x01;
            }
            else if (test_type == LOCK_STOP_TEST)
            {
                dataBuff[1] = 0x04;
            }
            else if(test_type == MOTOR_TEST_MODE )//自学习
            {
                dataBuff[1] = 0x02;
            }
//            else if(test_type == HALL_OC_TEST_MODE)//挡片测试
//            {
//                dataBuff[1] = lock->sensorTestStatus[0];
//                dataBuff[2] = lock->sensorTestStatus[1];
//            }
            ExtKds_Send(CMD_LOCKBODY_TEST, &dataBuff, 3, NULL); //ack
            test_type = 0xff;
        }
        if (isKeyPressed && test_type == KEY_TEST)
        {
            ATE_ButtonReport(dataBuff);
        }
    }
}



static uint8_t Ate_SetEncKeyTest(uint8_t type)
{
    uint8_t res =0x81;
    if(type ==  0)//人脸
    {
       newFaceReportFlag = 1; 
       res =  ATE_Set_Face_Enc_Key();
    }
    else  if(type == 1)//掌静脉
    {
        PalmVein_Ctrl(PALMVEIN_CTRL_SET_RELEASE_ENC,0,0);
        test_type = PVN_TEST;
        res =0X80;
    }
    return res;
}



static void Ate_ExtendKdsMsgCb(void *msg, uint16_t len)
{
    ExtendKdsMsg_t *extend_kds = (ExtendKdsMsg_t *)msg;
    if (extend_kds->msgType == EXT_RECV_CMD_PACKET)
    {
        uint16_t ack_len = 0;
        uint8_t *ack_data = NULL;

        if (msg == NULL || len == 0)
        {
            ATE_MAIN_LOG("msg is null\r\n");
            return;
        }

        ATE_MAIN_LOG("Ate receive cmd : %02X", extend_kds->cmd);

        if (extend_kds->cmd == CMD_START_OTA) //启动OTA
        {
            ATE_FirmwareUpdate(extend_kds->data[0]);  //! 厂内升级固件
            return;
        }

        ack_data = OSAL_Malloc(256);
        memset(ack_data, 0x00, 256);

        test_type = 0xff;
        if (extend_kds->cmd != CMD_CHANGE_WORK_MODE)
        {
            if (productionTestMode != TESTMODE_TESTING)
            {
                if (extend_kds->cmd == CMD_READ_ANY_RECORDS) //读门锁记录，公京检需求
                {
                    ack_data[0] = ATE_ReadRecords(extend_kds->data, &ack_data[1], &ack_len);
                    ExtKds_Send(extend_kds->cmd, ack_data, ack_len + 1, NULL);
                    OSAL_UpdateSleepTime(10000, 0);
                }
                if(ack_data) OSAL_Free(ack_data);
                return;
            }
        }
        if(lcd_test_flag == 1 && extend_kds->cmd != CMD_OLED_TEST)
        {
            lcd_test_flag =0;
            Lcd_StopDisplay();
        }
        switch (extend_kds->cmd)
        {
        case CMD_CHANGE_WORK_MODE:
            ack_data[0] = ATE_ChangeWorkMode(extend_kds->data); //! 改变工作模式
            break;
        case CMD_SET_DOORLOCK_PARA: //! 设置门锁参数
            ack_data[0] = ATE_SetDoorLockPara(extend_kds->data, extend_kds->len, &ack_data[1], &ack_len);
            break;
        case CMD_BLE_CAL:
            ack_data[0] = ATE_BleCal(extend_kds->data, extend_kds->len, &ack_data[1], &ack_len); //! 蓝牙频偏校准
            break;
        case CMD_BLE_FRE_TEST:
            ack_data[0] = ATE_BleFreTest(extend_kds->data, extend_kds->len); //! 蓝牙RF定频测试
            break;
        case CMD_EXTEND_NETWORK_SET:
            ack_data[0] = ATE_ExtendNetworkSet(extend_kds->data); 
            break;
        case CMD_FVN_TEST:
            ack_data[0] = ATE_FvnTest(); //! 指静脉测试
            break;
        case CMD_READ_LOCK_VOLTAGE:
            if(extend_kds->len == 1)
            {
               newBatTestFlag =1;
            }
            else
            {
                newBatTestFlag =0;
            }
            ack_data[0] = ATE_ReadLockVoltage(extend_kds->data,&ack_data[1], &ack_len); //! 读取门锁电压
            break;
        case CMD_TOUCH_TEST:
            ack_data[0] = ATE_TouchTest(); //! 按键测试
            break;
        case CMD_FPT_TEST:
            ack_data[0] = ATE_FptTest(); //! 指纹测试
            break;
        case CMD_CARD_TEST:
            ack_data[0] = ATE_CardTest(); //! 卡片测试
            break;
        case CMD_LOCKBODY_TEST: //! 锁体测试
            ack_data[0] = ATE_LockBodyTest(extend_kds->data, &ack_data[1], &ack_len);
            break;
        case CMD_READ_VERSION:
            ack_data[0] = ATE_ReadSoftVersion(&ack_data[1], &ack_len); //! 读取软件版本号
            break;
        case CMD_READ_WRITE_SECURITYCODE:
            ack_data[0] = ATE_ReadWriteSecurityCode(extend_kds->data, extend_kds->len, &ack_data[1], &ack_len); //! 读写防伪码
            break;
        case CMD_READ_LOCK_TIME:
            ack_data[0] = ATE_ReadLockTime(&ack_data[1], &ack_len); //! 读取门锁时间
            break;
        case CMD_LOCK_SLEEP:
            ack_data[0] = ATE_SystemSleep(extend_kds->data); //! 系统休眠
            break;
        case CMD_KEYBOARD_LIGHT_TEST:
            ack_data[0] = ATE_KeyBoardLedTest(extend_kds->data, extend_kds->len); //! 指示灯测试
            break;
        case CMD_PLAY_AUDIO:
            ack_data[0] = ATE_PlayAudio(extend_kds->data, extend_kds->len, &ack_data[1], &ack_len); //! 声音测试
            break;
        case CMD_BLUETOOTH_TEST:
            ack_data[0] = ATE_ReadBleMac(&ack_data[1], &ack_len); //! 获取蓝牙MAC
            break;
        case CMD_WRITE_BLE_KEY:
            ack_data[0] = ATE_WriteBleKey(extend_kds->data, extend_kds->len, &ack_data[1], &ack_len); // 写入蓝牙密钥
            break;
        case CMD_WRITE_BLE_SN:
            ack_data[0] = ATE_WriteBleSN(extend_kds->data, extend_kds->len, &ack_data[1], &ack_len); //! 写蓝牙SN
            break;
        case CMD_STUDY_NEXT_TIME_FLAG:    
            ack_data[0] = ATE_SetAutoCalFlag(extend_kds->data);   
            break;
        case CMD_LED_CTRL:
            ack_data[0] = ATE_LedControl(extend_kds->data); //! LED控制
            break;
        case CMD_RECOVERY:
            ack_data[0] = ATE_Recovery(); //! 恢复出厂
            break;
        case CMD_EEPROM_RESTORE:
            ack_data[0] = ATE_EepromRecovery(extend_kds->data, extend_kds->len); //! 清空eeprom
            break;
#ifndef WIFI_TYPE_XUNMEI
//        case CMD_WR_SERVICE_INFO:
//            ack_data[0] = ATE_WrServiceInfo(extend_kds->data, extend_kds->len,&ack_data[1], &ack_len);
//            break;
#else
        case CMD_WR_SERVICE_INFO:
            ack_data[0] = ATE_XMServiceInfo(extend_kds->data, extend_kds->len,&ack_data[1], &ack_len);
            break;
#endif
        case CMD_GSENSOR_TEST:
            ack_data[0] = ATE_GsensorTest(); // 加速度
            break;
        case CMD_MSENSOR_TEST:
            Msensor_Setting(MSENSOR_SELF_TEST, SET); // 门磁测试
            OSAL_Free(ack_data);
            return;
        case CMD_FACE_TEST:
            if(extend_kds->len == 2)
            {
                ack_data[0] =  ATE_FacePvnTest(extend_kds->data); //人脸掌静脉测试
            }
            else 
            {
                newFaceReportFlag =0;
                ack_data[0] = ATE_FaceTest(extend_kds->data); //人脸测试
            } 
            break;
        case CMD_TOF_TEST:
            ack_data[0] = ATE_DistanceTest(extend_kds->data); //距离测试
            break;
        case CMD_TOF_CAL:
            ack_data[0] = ATE_DistanceCal(); //距离传感器校准
            break;
        case CMD_SET_FACE_ENC_KEY_TEST:
            if(extend_kds->len == 1)
            {
               ack_data[0] = Ate_SetEncKeyTest(extend_kds->data[0]);
            }
            else 
            {
                ack_data[0] = ATE_Set_Face_Enc_Key();
            }
            break;
        case CMD_TEST_READ_MODE_VERSION:
            ack_data[0] = ATE_ReadModeVersion(extend_kds->data, &ack_data[1], &ack_len);
            break;
        case CMD_PSENSOR_TEST: //惯性传感器测试
            ack_data[0] = ATE_PSensorTest(extend_kds->data);
            break;
        // case CMD_READ_REARBOARDVERSION: //读取后板版本号
        //     ack_data[0] = ATE_ReadOtherBoardVersion(&ack_data[1], &ack_len);
        //     break;
        case CMD_READ_KDSWIFI_VERSION:
            ack_data[0] = ATE_ReadKDSWifiVersion(&ack_data[1], &ack_len);
            break;
        case CMD_WIFI_BLE_MAC:
            ack_data[0] = ATE_ReadWifiBleMac(extend_kds->data[0], &ack_data[1], &ack_len);
            break;
        case CMD_TEST_INT_IO: //讯美IO测试
            ack_data[0] = ATE_XM_IoTest();
            break;
        case CMD_OLED_TEST: //显示屏测试
            if(lcd_test_flag)
            lcd_test_flag =1;
            ack_data[0] = ATE_LcdTest(extend_kds->data[0]);
            break;
        case CMD_XM_WIFI_RSSI_TEST: //WIFI rssi测试
        #if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
            ack_data[0] = ATE_KDS_WifiRssiTest(extend_kds->data, extend_kds->len);
        #else
            ack_data[0] = ATE_XM_WifiRssiTest(extend_kds->data, extend_kds->len);
        #endif
            break;
        case CMD_OTA_LINK_TEST: //讯美OTA相关通信接口测试
            ack_data[0] = ATE_XM_OtaRelatedTest(extend_kds->data[0]);
            break;
        case CMD_HIGH_SPEED_HALL_TEST: //高速霍尔测试
            ack_data[0] = ATE_HighSpeedHallTest();
            break;
#ifdef CAMERA_SUB_DEVICE
        case CMD_XM_VIDEO_TEST:   //视频测试
            Camera_Start_QrcodeScan(60); //启动二维码扫描
            ack_data[0] = CMD_EXE_OK;
            break;
        case CMD_XM_VOICE_TEST:   //声音测试
            Camera_AudioTest();
            ack_data[0] = CMD_EXE_OK;
            break;
        case CMD_XM_PIR_TEST:
            //TODO PIR测试，调用PIR组件
            SYS_CALL(Pir_AteCheck);
            ack_data[0] = CMD_EXE_OK;
            break;
        case CMD_XM_RED_LED_TEST:/* 测试补光灯 */
            {
                uint8_t onoff = extend_kds->data[0];
                if (onoff == 1)
                {
                    Led_Set("LED", LED_OFF, 0, 0); //键盘灯
                }
                Camera_SetFillLight(onoff);
            }
            ack_data[0] = CMD_EXE_OK;
            break;
#else
        case CMD_XM_MIC_TEST:     //mic测试
        case CMD_XM_VOICE_TEST:   //声音测试
        case CMD_XM_RED_LED_TEST: //红外补光灯测试
        case CMD_XM_VIDEO_TEST:   //视频测试
            ack_data[0] = ATE_XM_PeripheralsTest(extend_kds->cmd, extend_kds->data[0]);
            break;
        case CMD_XM_PIR_TEST:     //pir测试
            ack_data[0] = ATE_XM_PeripheralsTest(extend_kds->cmd, extend_kds->data[0]);
            break;
#endif /* END OF  CAMERA_SUB_DEVICE*/
        case CMD_XM_SET_LANGUAGE:   // 设置讯美模块的语言
            ack_data[0] = ATE_RemoteXm_SetLanguage( extend_kds->data[0] );
            break;
        case CMD_XM_IN_OUT_TEST_MODE: //讯美模组进入退出产测模式
            ack_data[0] = ATE_XM_InOutTestMode(extend_kds->data[0]);
            break;
        case CMD_SET_SERVER_PARA: //配置服务器参数
        #if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
            ack_data[0] = ATE_KDS_SetServerPara(extend_kds->data, extend_kds->len);
        #else
            ack_data[0] = ATE_XM_SetServerPara(extend_kds->data, extend_kds->len);
        #endif
            break;
        case CMD_READ_SERVER_PARA: //读取服务器参数
        #if defined(WIFI_SUB_DEVICE) || defined(CAMERA_SUB_DEVICE)
            ack_data[0] = ATE_KDS_ReadServerPara(&ack_data[1], &ack_len);
        #else
            ack_data[0] = ATE_XM_ReadServerPara(extend_kds->data, extend_kds->len);
        #endif
            break;
        case CMD_SET_LOGO: //配置开机logo
        #ifdef CAMERA_SUB_DEVICE
            ack_data[0] = ATE_KDS_SetLogo(extend_kds->data, extend_kds->len);
        #else
            ack_data[0] = ATE_XM_SetLogo(extend_kds->data, extend_kds->len);
        #endif
            break;
        case CMD_READ_LOGO: //读取开机logo
        #ifdef CAMERA_SUB_DEVICE
            ack_data[0] = ATE_KDS_ReadLogo(&ack_data[1], &ack_len);
        #else
            ack_data[0] = ATE_XM_ReadLogo(extend_kds->data, extend_kds->len);
        #endif
            break;
        case CMD_LOCK_DAI_TEST: //锁体测试
            ack_data[0] = ATE_LockDaiTest();
            OSAL_Free(ack_data);
            return;
        // case CMD_READ_HANDLE_VERSION:
        //     ack_data[0] = ATE_ReadHandleVersion(&ack_data[1], &ack_len);
        //     break;
        case CMD_XM_READ_WIFI_MAC:
            ack_data[0] = ATE_ReadXMWifiMac(&ack_data[1], &ack_len); // 获取WiFi mac地址
            break;
        case CMD_MANUAL_LOCK_DAI_TEST:
            ack_data[0] = ATE_ManulLockDaiTest();
            OSAL_Free(ack_data);
            return;
        case CMD_EXTERN_MOTO://外置电机测试
            ack_data[0] = ATE_ExternMotoTest(extend_kds->data[0]);
            break;
        // case CMD_OLED_TEST://OLED 测试
        //     ack_data[0] =ATE_OledTest(extend_kds->data[0]);
        //     break;
        case CMD_READ_ALL_VERSION: // 各种版本号查询
            ack_data[0] = ATE_ReadAnyVersion((DFU_DevNum_enum_t)extend_kds->data[0], &ack_data[1], &ack_len);
            DFU_devnum = (DFU_DevNum_enum_t)extend_kds->data[0];
            break;
        case CMD_READ_ERROR_CODE: //读取故障码
            ack_data[0] = ATE_ReadErrorCode(&ack_data[1], &ack_len);
            break;
        case CMD_XUNMEI_DEV_TEST://讯美外设测试
            ack_data[0] = ATE_XunmeiDevTest(extend_kds->data);
            break;

        case CMD_NB_CSQ:  
            ack_data[0] = ATE_ReadNB_CSQ();
            break;

        default:
            ack_data[0] = CMD_EXECUTING;
            break;
        }

        ATE_MAIN_LOG("ack ret :%02X",ack_data[0]);
        if (ack_data[0] != CMD_EXECUTING)
        {
            ExtKds_Send(extend_kds->cmd, ack_data, ack_len + 1, NULL); //发送ACK
        }

        if (ack_data != NULL)
        {
            OSAL_Free(ack_data);
        }

        if (extend_kds->cmd == CMD_TOF_CAL) //距离传感器上电不能放在校准函数里面  会阻塞CPU两秒 导致后板的发送状态及出错
        {
            SYS_CALL(dsensor_power_ctrl, ENABLE);
            if (extend_kds->len == 0)
            {
                SYS_CALL(dsensor_calibration);
            }
            else if (extend_kds->len == 1)
            {
                SYS_CALL(dsensor_calibration_ex, extend_kds->data[0]);
            }
        }
        if(extend_kds->cmd == CMD_HIGH_SPEED_HALL_TEST)//测试高速霍尔传感器
        {
           ATE_MAIN_LOG("Lock_TestCtrl HALL_TEST_MODE\r\n");
           Lock_TestCtrl(HALL_TEST_MODE,NULL,0); 
        }
    }
    else if (extend_kds->msgType == EXT_EXEC_CB)
    {
        if (extend_kds->cmd == 0xB0)//过滤入网指令
        {
            return;
        }
        ATE_MAIN_LOG("cb: %x, cmd: %02x, len: %02x\r\n", extend_kds->cb, extend_kds->cmd, extend_kds->len);
        if (extend_kds->cb)
        {
            extend_kds->cb(extend_kds->cmd, extend_kds->data, extend_kds->len);
        }
    }
}

static ErrorStatus Ate_SleepCb(void)
{
    ATE_MAIN_LOG("Ate_main sleep_cb\r\n");
    return SUCCESS;
}

typedef enum
{
    TOUCH_HANDLE_PAD1,
    TOUCH_HANDLE_PAD2,
    TOUCH_HANDLE_IR,
} touch_handle_stu_t;

static uint8_t IrSensorABFlag =0;
/**
  * @brief  感应把手检测处理
  * @param  id 
  * @param  action 动作
  */
static void ATE_TouchHandleProcess(touch_handle_stu_t id, uint8_t action)
{
    static uint8_t touch_handle_status = 0;
    uint8_t dataBuf[4] = {0XFF, 0XFF, 0XFF, 0XFF};
    uint8_t isKeyPressed = 0;
    if (action == USER_ACTION_PRESS || action == USER_ACTION_LONG_PRESS)
    {
        touch_handle_status |= (1 << id);
    }
    else
    {
        touch_handle_status &= ~(1 << id);
    }
    ATE_MAIN_LOG("touch_handle_status: %x\r\n", touch_handle_status);
    if ((touch_handle_status & 0x05) == 0x05)
    {
        #ifdef IR_SENSOR_YIMING
        if(IrSensorABFlag == 0x03)
        #endif
        {
            dataBuf[1] = 0x07;
            isKeyPressed = 1;
        }
    }
    else if ((touch_handle_status & 0x06) == 0x06)
    {
        #ifdef IR_SENSOR_YIMING
        if(IrSensorABFlag == 0x03)
        #endif
        {
            dataBuf[1] = 0x08;
            isKeyPressed = 1;
        }
    }
    if (isKeyPressed)
    {
        ATE_ButtonReport(dataBuf);
    }
}


/**
  * @brief  IR组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void ATE_IrSensorCb(void *msg, uint16_t len)
{
    IRsensorMsg_t *ir_sensor = (IRsensorMsg_t *)msg;
    if (test_type == KEY_TEST) //当前处于按键测试
    {
        ATE_MAIN_LOG("ATE_IrSensorCb, action: %d, distance: %d\r\n", ir_sensor->action, ir_sensor->distance);
        #ifdef IR_SENSOR_YIMING
        if(ir_sensor->action == USER_ACTION_PRESS || ir_sensor->action == USER_ACTION_LONG_PRESS)
        {
            if(ir_sensor->addr == 0x49)//mn29xxx
            {
                IrSensorABFlag |=0x01;
            }
            else if(ir_sensor->addr == 0x48)//stk3x3x 
            {
                IrSensorABFlag |=0x02;
            }
        }
        else
        {
            if(ir_sensor->addr == 0x49)//mn29xxx
            {
                IrSensorABFlag &= ~(1 << 1);
            }
            else if(ir_sensor->addr == 0x48)//stk3x3x 
            {
                IrSensorABFlag &= ~(1 << 2);
            }
        }
        #endif
        ATE_TouchHandleProcess(TOUCH_HANDLE_IR, ir_sensor->action);
    }
}

/**
  * @brief  BUTTON组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void ATE_ButtonMsgCb(void *msg, uint16_t len)
{
    ButtonMsg_t *button = (ButtonMsg_t *)msg;

    if (button->action == 0xFF && button->times == 0xFF)
    {
        printf("Pan Xin touch ver: ");
        for (int i = 0; i < 4; i++)
        {
            printf("%02X ", button->name[i]);
        }
        printf("\r\n");
        memcpy(handle_version, button->name, 4);
    }

    if (test_type == KEY_TEST) //当前处于按键测试
    {
        ATE_MAIN_LOG("button->name :%s, time :%d\r\n", button->name, button->times);
        uint8_t dataBuf[4] = {0XFF, 0XFF, 0XFF, 0XFF};
        uint8_t isKeyPressed = 0;
        if (strcmp(button->name, "BUT_CLOSE") == 0) //关门按键
        {
            #ifdef DL5
            Led_Set("LED_RED", LED_FLASH, 1, 600);
            Led_Set("LED_GREEN", LED_OFF, 0, 0);
            #endif

            if (button->action == USER_ACTION_PRESS)
            {
                Led_Set_Rear("LED_BACK_R", LED_ON, 0, 0);
            }
            else if (button->action == INPUT_PORT_STA_RELEASE)
            {
                Led_Set_Rear("LED_BACK_R", LED_OFF, 0, 0);
            }

            #ifndef KDS_INDUCTIVE_HANDLE            //< kaadas感应把手: 旧方案（赛普拉斯P4处理器）没有关闭感应把手的菜单 
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x06;
                isKeyPressed = 1;
            }
            #else                                       // KDS感应把手使用1,2,3个脉冲来表示close/open/handle 
            if (button->action == USER_ACTION_RELEASE) 
            {                              
                switch( button->times )
                {
                    case 0: dataBuf[1] = 0x06; break;
                    case 1: dataBuf[1] = 0x05; break; 
                    case 2: dataBuf[1] = 0x07; break;
                    defualt: break; 
                }
                isKeyPressed = 1;
            }
            #endif
        }
        else if (strcmp(button->name, "BUT_OPEN") == 0) //开门按键
        {
            #ifdef DL5
            Led_Set("LED_RED", LED_OFF, 0, 0);
            Led_Set("LED_GREEN", LED_FLASH, 1, 600);
            #endif

            if (button->action == USER_ACTION_PRESS)
            {
                Led_Set_Rear("LED_BACK_G", LED_ON, 0, 0);
            }
            else if (button->action == INPUT_PORT_STA_RELEASE)
            {
                Led_Set_Rear("LED_BACK_G", LED_OFF, 0, 0);
            }

            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x05;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_KEY") == 0) //机械钥匙传感器动作
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[3] = 0x02;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_RESET") == 0) //恢复出厂设置按键
        {
            if (button->action == USER_ACTION_RELEASE && button->times == 0)
            {
                dataBuf[1] = 0x02;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_DAMAGE") == 0)
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x03;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_MODE") == 0) //手动模式
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[2] = 0x00;
                isKeyPressed = 1;
            }
            else if (button->action == USER_ACTION_RELEASE) //自动模式
            {
                dataBuf[2] = 0x01;
                isKeyPressed = 1;
            }
        }
        else if (strcmp("BUT_COVER_CHECK", button->name) == 0) //滑盖
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[2] = 0x04;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_TOUCH1") == 0)
        {
            ATE_TouchHandleProcess(TOUCH_HANDLE_PAD1, button->action); //感应把手pad1
        }
        else if (strcmp(button->name, "BUT_TOUCH2") == 0)
        {
            ATE_TouchHandleProcess(TOUCH_HANDLE_PAD2, button->action); //感应把手pad2
        }
        else if (strcmp(button->name, "BUT_HALL_KN") == 0) //旋转霍尔
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x09;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_Doorbell") == 0)            // 门铃测试
        {
            if (button->action == USER_ACTION_PRESS)
            {
                Audio_PlayDoorbell(HUAN_YING_YIN, 2);
                SYS_CALL(Remote_DoorBellNotify);
                dataBuf[0] = 'D';
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_D_SENSOR") == 0)            // 红外感应测试
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x12;
                isKeyPressed = 1;
            }
        }
        else if (strcmp(button->name, "BUT_SET") == 0)            // 配网按键
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x13;
                isKeyPressed = 1;
            }
        } 
        else if (strcmp(button->name, "BUT_FPT_RADAR") == 0)         // 超声波指纹雷达 
        {
            if (button->action == USER_ACTION_PRESS)
            {
                dataBuf[1] = 0x15;
                isKeyPressed = 1;
            }
        }         
#ifdef CAMERA_SUB_DEVICE
    else if (strcmp("SHOW_KEY",button->name) == 0)  /* 屏幕唤醒键 */
    {
        if (button->action == USER_ACTION_PRESS)
        {
            Camera_DisplayPicture(HI_PIC_LOGO_KDS,100, 5); 
            dataBuf[1] = 0x0B;
            isKeyPressed = 1;
        }
    }
#endif //END OF CAMERA_SUB_DEVICE
        if (isKeyPressed && test_type == KEY_TEST)
        {
            ATE_ButtonReport(dataBuf);
        }
    }
}

/**
  * @brief  BLE组件消息回调
  * @note   
  *
  * @param  msg 消息指针
  * @param  len 消息数据长度
  * @return void
  */
static void ATE_BleMsgCb(void *msg, uint16_t len)
{
    BlePublishMsg_t *ble_msg = (BlePublishMsg_t *)msg;
    if (ble_msg->type == PUBLISH_BLE_MAC) // MAC
    {
        /* mac地址翻转 */
        for (uint8_t i = 0; i < 6; i++)
        {
            bleMacSaveAddr[i] = ble_msg->pData[5 - i];
        }
        ATE_MAIN_LOG("ble_msg->pData:%02X%02X%02X%02X%02X%02X\r\n", ble_msg->pData[0], ble_msg->pData[1],
            ble_msg->pData[2], ble_msg->pData[3], ble_msg->pData[4], ble_msg->pData[5]);
    }
}

/**
  * @brief  系统消息回调
  * @note   故障码消息
  * @param  *msg
  * @param  len
  * @return void
  */
static void ATE_SysMsgCb(void *msg, uint16_t len)
{
    uint32_t temp = err_code;
    uint16_t value = *(uint16_t *)msg;
    ATE_MAIN_LOG("ATE_SysMsgCb: %04x\r\n", value);

    uint8_t err_type = value & 0xff;
    switch(err_type)
    {
        case ERRCODE_TYPE_DSENSOR:
        case ERRCODE_TYPE_FACE:
            if (SYS_CALL(Users_GetKeysQty, USERS_TYPE_FACE) == 0)
            {
                return;
            }
            break;
        case ERRCODE_TYPE_NFC:
            if (SYS_CALL(Users_GetKeysQty, USERS_TYPE_CARD) == 0)
            {
                return;
            }
            break;
        case ERRCODE_TYPE_FINGER:
            if (SYS_CALL(Users_GetKeysQty, USERS_TYPE_FPT) == 0)
            {
                return;
            }
            break;
        default:
            break;
    } 
    
    if ((value & 0xff) > 31)
    {
        return; //异常数据
    }
    if (value & 0xff00)
    {
        err_code |= (1 << (value & 0xff));
    }
    else
    {
        err_code &= ~(1 << (value & 0xff));
    }
    ATE_MAIN_LOG("ate update err code: %08x\r\n", err_code);
    if (temp != err_code)
    {
        if (productionTestMode != TESTMODE_TESTING && productionTestMode != TESTMODE_AGING)
        {
            SYS_CALL(Remote_UpdateErrCode, err_code);
        }
    }
}

/**
 * @brief 获取从机端口状态（确认有没有同步成功vTask）
 * 
 */
static void ATE_CheckSlaveStatus(TimerHandle_stu_t handle)
{
    int channel = -1;

    while (1)
    {
        int rc = OSAL_GetSlaveStatus(++channel);
        if (rc < 0)
        {
            break;
        }
        else
        {
            uint16_t msg = (rc << 8);

            if (channel == 0)
            {
                msg |= ERRCODE_TYPE_COM_FRONT_REAR;
            }
            else if (channel == 1)
            {
                msg |= ERRCODE_TYPE_COM_FRONT_WIFI;
            }
            else
            {
                continue;
            }

            ATE_MAIN_LOG("osport channel %d, status:%d\r\n", channel, rc);
            ATE_SysMsgCb(&msg, sizeof(msg));
        }
    }
}

#ifdef CAMERA_SUB_DEVICE
static void ATE_PirCb(void *msg, uint16_t len)
{
    PirMsg_t *pmsg = (PirMsg_t *)msg;

    uint8_t data[2] = {0x57, 0x00};
    if (pmsg->alarm == 2)
    {
        ATE_MAIN_LOG("HOVER ALARM");
        ExtKds_Send(CMD_XM_PERIPHERAL_REPORT, data, 2, extend_kds_send_callback); //上报
        
    }
}
/**
 * @description: camera组件消息处理
 * @note: 上报视频测试结果
 * @param {void} *msg
 * @param {uint16_t} len
 * @return {*}
 */
static void ATE_CameraCb(void *msg, uint16_t len)
{
    camera_ctrl_msg_t *camera = (camera_ctrl_msg_t *)msg;         
    switch (camera->msg_type)
    {
    case CAM_MSGTYPE_QRCODE_SCAN_REPLY:
        {
            ATE_MAIN_LOG("Recv:%s,len:%u",camera->payload,len);
            uint8_t data[2] = {0x56, 0x01};
            if (strcmp(camera->payload,VIDEO_TEST_QRCODE_STRING) == 0)
            {
                data[1] = 0x00;    
            }
            ExtKds_Send(CMD_XM_PERIPHERAL_REPORT, data, 2, NULL); //上报
        }
        break;
    case CAM_MSGTYPE_FW_VERSION:
        {
            hi_fw_version_stu_t *version = (hi_fw_version_stu_t*)(camera->payload);
            uint8_t ack_data[64] = {0};
            ack_data[0] = CMD_EXE_OK;
            strncpy(video_ver,version->video,sizeof(video_ver));
            strncpy(uvc_ver,version->uvc,sizeof(uvc_ver));
            ATE_MAIN_LOG("uvc version: %s", uvc_ver);
            ATE_MAIN_LOG("video version: %s", video_ver);
            if (DFU_devnum == DFU_DEVNUM_VIDEO_MODULE)
            {
                memcpy(&ack_data[1],video_ver,strlen(video_ver));
                ExtKds_Send(CMD_READ_ALL_VERSION, ack_data, strlen(video_ver) + 1, NULL); //发送ACK
            }
            else if (DFU_devnum == DFU_DEVNUM_UVC)
            {
                memcpy(&ack_data[1],uvc_ver,strlen(uvc_ver));
                ExtKds_Send(CMD_READ_ALL_VERSION, ack_data, strlen(uvc_ver) + 1, NULL); //发送ACK
            }
            DFU_devnum = DFU_DEVNUM_MAX;
        }
        break;
    default:
        break;
    }
}
#endif  /* END OF CAMERA_SUB_DEVICE */


#ifdef BAT_ENCRY
/**
 * @brief 电池加密消息
 * 
 */
static void ATE_BatEncryCb(void *msg, uint16_t len)
{
    static uint8_t PowerOn_flag = 0x00; //测试类型
    if(PowerOn_flag == 0x11)
    {
        return;
    } 
    uint8_t *BatMsg = (uint8_t*)msg;
    ATE_MAIN_LOG("Bat Encrypt enum: %d",BatMsg[0]);
    if(BatMsg[0] == BAT_ENCRY_REPORT_INFO)
    {
        Bat_Encrypt_Msg_t *bat = (Bat_Encrypt_Msg_t *)&BatMsg[1];
        memset(&(AteBatInfo.encBatInfo),0,sizeof(Bat_Encrypt_Msg_t));
        memcpy(&(AteBatInfo.encBatInfo),bat,sizeof(Bat_Encrypt_Msg_t));
    }
    else if(BatMsg[0] == BAT_ENCRY_GET_PAGE2)
    {
        Bat_Encrypt_PAGE2_t *bat = (Bat_Encrypt_PAGE2_t *)&BatMsg[1];
        memset(&(AteBatInfo.BatPage2),0,sizeof(Bat_Encrypt_PAGE2_t));
        memcpy(&(AteBatInfo.BatPage2),bat,sizeof(Bat_Encrypt_PAGE2_t));
    }
    else if(BatMsg[0] == BAT_ENCRY_GET_PAGE3)
    {
        Bat_Encrypt_PAGE3_t *bat = (Bat_Encrypt_PAGE3_t *)&BatMsg[1];
        memset(&(AteBatInfo.BatPage3),0,sizeof(Bat_Encrypt_PAGE3_t));
        memcpy(&(AteBatInfo.BatPage3),bat,sizeof(Bat_Encrypt_PAGE3_t));
        PowerOn_flag |= 0x01;
    }
    else if(BatMsg[0] == BAT_ENCRY_GET_PAGE4)
    {
        Bat_Encrypt_PAGE4_t *bat = (Bat_Encrypt_PAGE4_t *)&BatMsg[1];
        memset(&(AteBatInfo.BatPage4),0,sizeof(Bat_Encrypt_PAGE4_t));
        memcpy(&(AteBatInfo.BatPage4),bat,sizeof(Bat_Encrypt_PAGE4_t));
        PowerOn_flag |= 0x10;
        
    }
}
#endif /* END OF BAT_ENCRY */


/**
 * @brief 延时初始化ate
 * @note 为解决老化模式下重新上电会先进ate再进local，导致休眠问题
 * 
 */
// static void ATE_DelayInit(TimerHandle_stu_t handle)
// {
//     ATE_Init();
// }

static void ATE_main(uint32_t wake_id, uint32_t wake_param)
{
    ATE_MAIN_LOG("ATE_main, wake_id:%ld, wake_param:%ld\r\n", wake_id, wake_param);
    if (wake_id == 0XFF)
    {
        OSAL_TimerCreate(ATE_CheckSlaveStatus, 5000, RESET);
    }
    app_handle = OSAL_AppCreate("APP_ATE", Ate_SleepCb);
    OSAL_MessageSubscribe(app_handle, COMP_EXTEND_KDS, Ate_ExtendKdsMsgCb);
    OSAL_MessageSubscribe(app_handle, COMP_BUTTON, ATE_ButtonMsgCb);
    OSAL_MessageSubscribe(app_handle, COMP_BLE, ATE_BleMsgCb);
    OSAL_MessageSubscribe(app_handle, COMP_SYS_MSG, ATE_SysMsgCb);
    #ifdef CAMERA_SUB_DEVICE
    OSAL_MessageSubscribe(app_handle, COMP_CAMERA, ATE_CameraCb);
    #endif  /* END OF CAMERA_SUB_DEVICE */
    #ifdef BAT_ENCRY
    OSAL_MessageSubscribe(app_handle, COMP_BATTERY_ENCRY, ATE_BatEncryCb);
    #endif /* END OF BAT_ENCRY */

    ATE_Init();

    // ATE_FirmwareUpdate(16);
}
APP_INIT_EXPORT(ATE_main);